1 需求实现

1)需求实现

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

2)涉及技术栈

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

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】摇杆相关推荐

  1. Unity3D中使用Joystick Pack实现摇杆控制

    学更好的别人, 做更好的自己. --<微卡智享> 本文长度为2342字,预计阅读6分钟 前言 花了几个小时重新根据Unity3D的初学者教程做了一个简单的Demo,做完后确实对新人来说是个 ...

  2. Unity3D 游戏引擎之IOS自定义游戏摇杆与飞机平滑的移动(十一)

    Unity3D 游戏引擎之IOS自定义游戏摇杆与飞机平滑的移动 雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong. ...

  3. 【Unity3D插件】EasyTouch插件分享《手机摇杆插件》

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一.前言 这篇文章参考了很多博客,然后加入了一些自己的理解,从了解到深入都有 ...

  4. Unity3d项目入门之虚拟摇杆

    Unity本身不提供摇杆的组件,开发者可以使用牛逼的EasyTouch插件或者应用NGUI实现相关的需求,下面本文通过Unity自身的UGUI属性,实现虚拟摇杆的功能. 主参考 <Unity:使 ...

  5. Unity3D学习日记(二)使用UGUI制作虚拟摇杆控制摄像机

    前天撸了一个简单的UGUI虚拟摇杆,今天我就利用前天做的虚拟摇杆做了一个简单的摄像机控制器,主要看看UGUI虚拟摇杆是否可以完美的控制移动和旋转.(PS:主要是为接下来的项目做技术测试),手游版的CF ...

  6. 基于Unity3D ScrollRect的游戏摇杆实现

    ScrollRect是UGUI提供的基础拖动组件,给它的Content绑定一个滑块就能工作了.如图 代码如下: using UnityEngine; using UnityEngine.EventSy ...

  7. Unity3D for iOS初级教程:Part 2/3

    Unity3D for iOS初级教程:Part 2/3 这篇教材是来自教程团队成员 Christine Abernathy, 他是Facebook的开发支持团队的工程师. 欢迎来到Unity3D f ...

  8. Unity3D+VR的实现

    针对CardBoard一类的眼镜用Unity3D开发VR内容. 1.创建VRCamera: 使用Dive插件,从DiveUnityDemo提取摄像机和有关的脚本并export出来. 2.对象选择: 视 ...

  9. Unity3D脚本中文系列教程(八)

    ◆ static var matrix : Matrix4x4 描述:设置用于渲染所有gizmos的矩阵. 类方法 ◆ Static function DrawCube(center:Vector3, ...

  10. Unity3D引擎各大插件免费下载地址

    Unity3D引擎作为当前最主流的3D游戏引擎之一,拥有大量第三方插件和工具.以下为各大Unity3D引擎各大插件免费下载地址,还有一些热门插件例如:Playmaker . UnIDE .Tile B ...

最新文章

  1. 随想录(markdown基本语法)
  2. 分享这几天做seo优化的心得
  3. 【HDOJ】2266 How Many Equations Can You Find
  4. 分布式存储系统学习笔记(二)—分布式文件系统(4)—内容分发网络(CDN)
  5. Vmware 安装 Fedora 18 注意事项
  6. yacc和lex细节解答以及实现反向自动微分
  7. linux glibc升级
  8. PPT/Word中神奇的快捷键F4(重复上次操作)失效的解决办法
  9. 解决pr导入的视频在监控器里面画面会放大的问题
  10. Linux如何配置DNS服务器
  11. 7-2 前序序列创建二叉树
  12. APP推广技巧:APP营销推广的八种渠道你一定要了解!
  13. cdr软件百度百科_coreldraw是干嘛的?能做什么?cdr软件在哪儿下载?
  14. 网页怎么算切屏_十种切屏抓取方法(图形)
  15. 蚂蚁笔记 linux安装教程,群晖docker安装蚂蚁笔记安装教程
  16. 长度短点的uuid_如何压缩UUID长度?
  17. QFont/QFontInfo方法功能(QT5.12)
  18. 致2020年的高考:教育改变命运
  19. 19级赵同学推荐的十佳医疗图像处理论文
  20. 2010年世界杯分组

热门文章

  1. 寒武纪2021数字后端笔试题
  2. div左对齐与里面的内容偏左但是距离左边有点儿距离
  3. matplotlib报错:Glyph 25151 (\N{CJK UNIFIED IDEOGRAPH-623F}) missing from current font. func(*args)
  4. HBuilderX开发的uniapp项目运行到微信小程序开发者工具上的方法
  5. drawerLayout 抽屉的另一半,设置为透明的颜色
  6. java项目1(家庭收支记账软件)
  7. win7没有权限使用计算机的,Win7提示你可能没有权限使用网络资源|未授予用户在此计算机解决方法...
  8. 阿里云免费企业邮箱申请链接入口支持50账号数
  9. 毕业设计-基于SpringBoot体育运动场馆管理系统+开题报告-任务书等
  10. PE破解操作系统密码原理