【Unity3D】摇杆

news/2025/3/14 17:18:55/

1 需求实现

        1)需求实现

  • 鼠标拖拽摇杆球控制坦克移动;
  • 上下左右按键也可以控制坦克移动,并且摇杆球也同步移动;
  • 鼠标右键滑动,控制坦克转向;
  • 相机在玩家后上方的位置,始终跟随玩家,朝玩家正前方看;
  • 单击鼠标左键或按空格键控制坦克发射炮弹。

        2)涉及技术栈

  • Transform组件
  • 人机交互Input
  • 刚体组件Rigidbody
  • 相机跟随
  • Canvas渲染模式与锚点
  • UGUI之Image
  • UGUI回调函数

        本文代码资源见 → Unity3D 摇杆控制物体运动。

2 游戏对象

        1)游戏界面

        2)游戏对象层级结构

        3)Transform组件参数

        1. 玩家 Transform 组件参数

NameTypePositionRotationScaleColor/Texture
PlayerEmpty(0, 0.25, -5)(0, 0, 0)(1, 1, 1)#228439FF
BottonCube(0, 0, 0)(0, 0, 0)(2, 0.5, 2)#228439FF
TopCube(0, 0.5, 0)(0, 0, 0)(1, 0.5, 1)#228439FF
GunCylinder(0, 0, 1.5)(90, 0, 0)(0.2, 1, 0.4)#228439FF
FirePointEmpty(0, 1.15, 0)(0, 0, 0)(1, 1, 1)——

        补充:Player 游戏对象添加了刚体组件。 

        2. 地面和炮弹 Transform 组件参数

NameTypePositionRotationScaleColor/Texture
PlanePlane(0, 0, 0)(0, 0, 0)(10, 10, 10)GrassRockyAlbedo
BulletSphere(0, 0.5, -5)(0, 0, 0)(0.3, 0.3, 0.3)#228439FF

        补充:炮弹作为预设体拖拽到 Assets/Resources/Prefabs 目录下,并且添加了刚体组件。

        3. 摇杆 RectTransform 组件参数

NameTypeWidth/HeightPosAnchors
StickCanvas——————
BackgroundImage(100, 100)(75, 75, 0)(0, 0), (0, 0)
BallImage(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 运行效果


http://www.ppmy.cn/news/216851.html

相关文章

unity3D摇杆

转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6961080 本章博文的目的是利用上一章介绍的游戏摇杆来控制人物模型的移动&#xff0c;与行走动画的播放。 如上图所示Create中的文件夹male中存放着模型动画与贴图等&#xff0c;这个应该是美…

手游摇杆(一)最简单的四方向摇杆

手游摇杆&#xff1a; (零)摇杆设计原理 (一)最简单的四方向摇杆 (二)八方向摇杆和移动范围限制 (三)跟随式摇杆 摇杆是所有手游中不可或缺的功能&#xff0c;是最基本的操作方式&#xff0c;下面用cococ creator实现的一个简单的摇杆&#xff0c;后续功能将基于此优化。 一 场…

【功能实现】手机游戏虚拟摇杆功能实现

【UNITY3D】 声明&#xff1a; 查API和根据自己的想法实现此功能。如果你喜欢我这个实现&#xff0c;希望你能有所收获&#xff0c;如果你能改进那就更棒了&#xff0c;但如果你想直接拿走&#xff0c;希望标明出处。 只需要把脚本交给画布下的空物体,自行自定义以下内容&…

GIN框架(GOLANG)讲解如何疯速入门

1.初始化项目&#xff1a; 1.初始化项目&#xff1a;go mod init 2.下载gin框架&#xff1a;go get -u github.com/gin-gonic/gin 3.引入&#xff1a;import "github.com/gin-gonic/gin" 注意点&#xff1a; 报错&#xff1a;$GOPATH/go.mod exists but should …

Js 游戏虚拟摇杆

首先说明是从这个大神这里看到的 https://blog.csdn.net/cdnight/article/details/50751832?locationNum3&fps1 一看之后下载资源需要30个币&#xff0c;而且下面的评论说资源不全&#xff0c;于是打消了下载csdn资源的念头了&#xff0c;其实自己也没币了&#xff0c; …

android studio游戏摇杆开发教程,仿王者荣耀摇杆

李子果 原创。。。 最近在做一个山寨版的王者荣耀&#xff0c;刚开始做的时候毫无头绪 摇杆的多点触控做的特别烂 经过几天的思考已完美解决所有问题&#xff0c;下面就和大家分享下这个摇杆的开发思路&#xff08;此教程不包含游戏源码&#xff09; 若有不正之处&#xff0…

游戏摇杆编程

文章目录 前言摇杆介绍技术特性 源程序获取摇杆功能信息获取摇杆当前状态 前言 基于前面几篇博文的介绍&#xff0c;我们可以进行编程&#xff0c;以获取游戏遥感所传回的数据。 前文回顾&#xff1a; WindowsAPI之joystickapi(游戏摇杆)头文件Windows API 之joystickapi(游戏…

Arduino简单实例之四_PS2游戏摇杆

1) 说明&#xff1a; PS2 游戏双轴摇杆传感器模块由采用金属 PS2 摇杆电位器制作&#xff0c;具有(X,Y)2 轴模拟输出&#xff0c;(Z) 1路按钮数字输出。可制作遥控器等互动作品。 SW引脚按下去时输出低电平&#xff0c;反之输出高电平 2) 硬件&#xff1a; PS2游…