Unity3D摇杆
Posted little_fat_sheep
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D摇杆相关的知识,希望对你有一定的参考价值。
1 需求实现
1)需求实现
- 鼠标拖拽摇杆球控制坦克移动;
- 上下左右按键也可以控制坦克移动,并且摇杆球也同步移动;
- 鼠标右键滑动,控制坦克转向;
- 相机在玩家后上方的位置,始终跟随玩家,朝玩家正前方看;
- 单击鼠标左键或按空格键控制坦克发射炮弹。
2)涉及技术栈
本文代码资源见 → Unity3D 摇杆控制物体运动。
2 游戏对象
1)游戏界面
2)游戏对象层级结构
3)Transform组件参数
1. 玩家 Transform 组件参数
Name | Type | Position | Rotation | Scale | Color/Texture |
---|---|---|---|---|---|
Player | Empty | (0, 0.25, -5) | (0, 0, 0) | (1, 1, 1) | #228439FF |
Botton | Cube | (0, 0, 0) | (0, 0, 0) | (2, 0.5, 2) | #228439FF |
Top | Cube | (0, 0.5, 0) | (0, 0, 0) | (1, 0.5, 1) | #228439FF |
Gun | Cylinder | (0, 0, 1.5) | (90, 0, 0) | (0.2, 1, 0.4) | #228439FF |
FirePoint | Empty | (0, 1.15, 0) | (0, 0, 0) | (1, 1, 1) | —— |
补充:Player 游戏对象添加了刚体组件。
2. 地面和炮弹 Transform 组件参数
Name | Type | Position | Rotation | Scale | Color/Texture |
---|---|---|---|---|---|
Plane | Plane | (0, 0, 0) | (0, 0, 0) | (10, 10, 10) | GrassRockyAlbedo |
Bullet | Sphere | (0, 0.5, -5) | (0, 0, 0) | (0.3, 0.3, 0.3) | #228439FF |
补充:炮弹作为预设体拖拽到 Assets/Resources/Prefabs 目录下,并且添加了刚体组件。
3. 摇杆 RectTransform 组件参数
Name | Type | Width/Height | Pos | Anchors |
---|---|---|---|---|
Stick | Canvas | —— | —— | —— |
Background | Image | (100, 100) | (75, 75, 0) | (0, 0), (0, 0) |
Ball | Image | (40, 40) | (75, 75, 0) | (0, 0), (0, 0) |
3 脚本组件
1)CameraController
CameraController.cs
using UnityEngine;
public class CameraController : MonoBehaviour
private Transform player; // 玩家
private Vector3 relaPlayerPos; // 相机在玩家坐标系中的位置
private float targetDistance = 15f; // 相机看向玩家前方的位置
private void Start()
relaPlayerPos = new Vector3(0, 4, -8);
player = GameObject.Find("Player/Top").transform;
private void LateUpdate()
CompCameraPos();
private void CompCameraPos() // 计算相机坐标
Vector3 target = player.position + player.forward * targetDistance;
transform.position = transformVecter(relaPlayerPos, player.position, player.right, player.up, player.forward);
transform.rotation = Quaternion.LookRotation(target - transform.position);
// 求以origin为原点, locX, locY, locZ 为坐标轴的本地坐标系中的向量 vec 在世界坐标系中对应的向量
private Vector3 transformVecter(Vector3 vec, Vector3 origin, Vector3 locX, Vector3 locY, Vector3 locZ)
return vec.x * locX + vec.y * locY + vec.z * locZ + origin;
说明: CameraController 脚本组件挂在 MainCamera 游戏对象上。
2)PlayerController
PlayerController.cs
using System;
using UnityEngine;
public class PlayerController : MonoBehaviour
private Transform firePoint; // 开火点
private GameObject bulletPrefab; // 炮弹预设体
private StickController stick; // 摇杆控制器
private float tankMoveSpeed = 4f; // 坦克移动速度
private float tankRotateSpeed = 2f; // 坦克转向速度
private Vector3 predownMousePoint; // 鼠标按下时的位置
private Vector3 currMousePoint; // 当前鼠标位置
private float fireWaitTime = float.MaxValue; // 距离上次开火已等待的时间
private float bulletCoolTime = 0.15f; // 炮弹冷却时间
private void Start()
firePoint = transform.Find("Top/Gun/FirePoint");
bulletPrefab = (GameObject) Resources.Load("Prefabs/Bullet");
stick = GameObject.Find("Stick/Ball").GetComponent<StickController>();
private void Update()
Move();
Rotate();
Fire();
private void Move() // 坦克移动
float hor = Input.GetAxis("Horizontal");
float ver = Input.GetAxis("Vertical");
Move(hor, ver);
public void Move(float hor, float ver) // 坦克移动
if (Mathf.Abs(hor) > float.Epsilon || Mathf.Abs(ver) > float.Epsilon)
Vector3 vec = transform.forward * ver + transform.right * hor;
GetComponent<Rigidbody>().velocity = vec * tankMoveSpeed;
// stick.UpdateStick(new Vector3(hor, 0, ver));
Vector3 dire = new Vector3(hor, ver, 0);
dire = dire.normalized * Mathf.Min(dire.magnitude, 1);
stick.UpdateStick(dire);
private void Rotate() // 坦克旋转
if (Input.GetMouseButtonDown(1))
predownMousePoint = Input.mousePosition;
else if (Input.GetMouseButton(1))
currMousePoint = Input.mousePosition;
Vector3 vec = currMousePoint - predownMousePoint;
GetComponent<Rigidbody>().angularVelocity = Vector3.up * tankRotateSpeed * vec.x;
predownMousePoint = currMousePoint;
private void Fire() // 坦克开炮
fireWaitTime += Time.deltaTime;
if (Input.GetMouseButtonDown(0) && !IsMouseInUIArea() || Input.GetKeyDown(KeyCode.Space))
if (fireWaitTime > bulletCoolTime)
BulletInfo bulletInfo = new BulletInfo("PlayerBullet", Color.red, transform.forward, 10f, 15f);
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, Quaternion.identity);
bullet.AddComponent<BulletController>().SetBulletInfo(bulletInfo);
fireWaitTime = 0f;
private bool IsMouseInUIArea() // 鼠标在UI控件区域
Vector3 pos = Input.mousePosition;
return pos.x < 150 && pos.y < 150;
说明: PlayerController 脚本组件挂在 Player 游戏对象上。
3)StickController
StickController.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class StickController : MonoBehaviour, IDragHandler, IEndDragHandler
private Vector3 originPos; // 鼠标开始拖拽时位置
private Vector3 currPos; // 鼠标当前位置
private float radius; // 遥杆半径
private PlayerController player; // 玩家控制器
private Vector3 dire = Vector3.zero; // 摇杆球的方位
private void Start ()
originPos = transform.position;
radius = 50;
player = GameObject.Find("Player").GetComponent<PlayerController>();
private void Update ()
player.Move(dire.x, dire.y);
public void OnDrag(PointerEventData eventData)
Vector3 vec = Input.mousePosition - originPos;
dire = vec.normalized * Mathf.Min(vec.magnitude / radius, 1);
UpdateStick(dire);
public void OnEndDrag(PointerEventData eventData)
transform.position = originPos;
dire = Vector3.zero;
public void UpdateStick(Vector3 dire) // 更新摇杆位置
transform.position = originPos + dire * radius;
说明: StickController 脚本组件挂在 Ball 游戏对象上。
4)BulletController
BulletController.cs
using UnityEngine;
using UnityEngine.UI;
public class BulletController : MonoBehaviour
private BulletInfo bulletInfo; // 炮弹信息
private void Start ()
gameObject.name = bulletInfo.name;
GetComponent<MeshRenderer>().material.color = bulletInfo.color;
float lifeTime = bulletInfo.fireRange / bulletInfo.speed; // 存活时间
Destroy(gameObject, lifeTime);
private void Update ()
transform.GetComponent<Rigidbody>().velocity = bulletInfo.flyDir * bulletInfo.speed;
public void SetBulletInfo(BulletInfo bulletInfo)
this.bulletInfo = bulletInfo;
说明: BulletController 脚本组件挂在 Bullet 游戏对象上(代码里动态添加)。
5)BulletInfo
BulletInfo.cs
using UnityEngine;
public class BulletInfo
public string name; // 炮弹名
public Color color; // 炮弹颜色
public Vector3 flyDir; // 炮弹飞出方向
public float speed; // 炮弹飞行速度
public float fireRange; // 炮弹射程
public BulletInfo(string name, Color color, Vector3 flyDir, float speed, float fireRange)
this.name = name;
this.color = color;
this.flyDir = flyDir;
this.speed = speed;
this.fireRange = fireRange;
4 运行效果
声明:本文转自【Unity3D】摇杆
以上是关于Unity3D摇杆的主要内容,如果未能解决你的问题,请参考以下文章
Unity3D插件EasyTouch插件分享《手机摇杆插件》