最近想着自己动手做款游戏,算是工作之余练练手,游戏规模不需要多大,毕竟个人时间有限,能简单实现我想要的功能就好。就游戏的类型方向的选择,我之前考虑做手游MOBA方向,当然也尝试做了下,发现水有点深,况且自身能力还不足以支撑整个游戏的开发,所以退而求其次转战做款联机小游戏,怎么说之前也研究过网络通信这块。当前今天的主角不是联机小游戏,而是我在探索手游MOBA的时候,针对目前手游摇杆插件来定制自己的摇杆。
摇杆的构成与原理
目前通过Unity构造的手游,大多数的UI应该都是基于UGUI做的,本文的摇杆也是如此,准确来说其实也就是两个图片构成,具体构成图如下
摇杆能够控制角色移动的原理说来也不难,主要在于摇杆转动方向转化到角色前进的方向,UI控制的方向是二维的,角色移动需要的是三维的方向,有人觉得不晓得怎么转化,其实3D物体移动的时候垂直方向上是不太需要变化的,也就是说只需要我们将摇杆传递的二维偏移量转化成角色移动方向向量的其他两个值就可以了。
可能我说的不是很精简或者通俗,甚至于有错误也请多多包涵,批评指正,如下是效果图
代码解析
说了那么多,我还是以代码为例来具体说明摇杆是如何实现角色移动的
SticktController.cs
using UnityEngine;
using System;
public class SticktController : MonoBehaviour {
private RectTransform sticktTransform;
private RectTransform sticktBgTransform;
//private GameObject touchRotatePanel;
private Vector3 firstSticktPos;
private Vector2 firstSticktPos2;
private bool isUp = false;
private bool isDown = false;
private float backSpeed = 4f;
private float radius;
private float offsetX;
private float offsetY;
private float rotateX;
private float rotateY;
private Vector3 downMousePos;
public Action<float,float> OnMoveStickt;
public Action<float,float> OnTouchRotate;
public Action OnJumpClick;
public Action OnShootClick;
void Start () {
//touchRotatePanel = transform.Find ("TouchRotate").gameObject;
sticktTransform = transform.Find ("SticktBg/Stickt").GetComponent<RectTransform> ();
sticktBgTransform = transform.Find ("SticktBg").GetComponent<RectTransform> ();
firstSticktPos = sticktTransform.position;
firstSticktPos2 = sticktTransform.anchoredPosition;
radius = sticktBgTransform.sizeDelta.x / 2;
}
void Update () {
if (isUp) {
sticktTransform.position = Vector3.Lerp (sticktTransform.position,firstSticktPos,Time.deltaTime * backSpeed);
}
if (isDown) {
if (OnMoveStickt != null) {
OnMoveStickt (offsetX, offsetY);
}
}
}
public void OnSticktDrag(){
float distance = Vector3.Distance (sticktBgTransform.position, Input.mousePosition);
if (distance < radius) {
sticktTransform.position = Input.mousePosition;
} else {
Vector3 targetDirection = Input.mousePosition - firstSticktPos;
sticktTransform.position = firstSticktPos + targetDirection.normalized * radius;
}
offsetX = sticktTransform.position.x - firstSticktPos.x;
offsetY = sticktTransform.position.y - firstSticktPos.y;
}
public void OnPointerUp(){
isUp = true;
isDown = false;
}
public void OnPointerDown(){
isUp = false;
isDown = true;
}
//public void OnTouchDragRotate(){
// rotateX = Input.mousePosition.x - downMousePos.x;
// rotateY = Input.mousePosition.y - downMousePos.y;
// if (OnTouchRotate != null) {
// OnTouchRotate (rotateX, rotateY);
// }
//}
public void OnTouchDragDown(){
downMousePos = Input.mousePosition;
}
}
这段代码就是控制摇杆UI的,大体的功能实现大家可以从代码中找到答案,我说下大概的思路:鼠标点击摇杆的时候让摇杆跟随鼠标移动,但是有范围限制,受限于底座的圆形区域,一旦鼠标控制的摇杆到达限制区域的极限就让摇杆不再跟随鼠标,当然鼠标移动的方向即使是在极限区域的摇杆也是需要跟随的,鼠标抬起的时候摇杆会回弹到初始位置;至于如何控制角色行走主要在于代码中设定的委托OnMoveStickt ,传递出去的就是摇杆在屏幕的偏移量,需要将其绑定到角色移动脚本上就好了。
代码工程看这里
目前提供的代码只是针对摇杆UI的控制,至于要达到效果图中的样子还需要角色移动的脚本,我在这就不贴代码了,有兴趣的话可以看这里
后续
说到自己想做个联机小游戏,其实目前已经在做了,不过完成度不是很好,只能说基本完成功能,后面呢打算继续优化,当然也会分享出来具体的实现方案,今天就到这里~