《Unity5实战-使用C#和Unity开发多平台游戏》第二章-构建一个让你置身3D空间的演示
鼠标观察/键盘控制移动飞行/行走/碰撞检测
Unity版本:2019.4.23f1c1
- 注意脚本名称和组件添加,不在文章中一一强调
- 场景模型都是在资源商店选择的免费下载(选择Sort by Price(Low to High)排序)搜索参考关键字:airplane、sky
- 整篇的实例代码是修改累加的,为了防止混乱我就全部贴上,不强调新增或删减部分
搭建:一架飞机模型(脚本挂载物体),天空盒(照明设置),摄像机Camera
原始画面:
跟随鼠标观察周围脚本
运行效果:
如果改为鼠标X则只能水平旋转(我这里是摄像机角度有些倾斜,不是飞机
using UnityEngine;
using System.Collections;
public class MouseLook : MonoBehaviour
{
//观察周围
public enum RotationAxes
{
MouseXAndY=0,
MouseX=1,
MouseY=2
}
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityHor = 9.0f;//旋转速度
public float sensitivityVert = 9.0f;
public float miniumVert = -45.0f;
public float maximumVert = 45.0f;
private float _rotationX = 0;
void Start()
{
Rigidbody body = GetComponent<Rigidbody>();
if (body != null)
body.freezeRotation = true;
}
// Update is called once per frame
void Update()
{
if (axes == RotationAxes.MouseX)//水平旋转
{
transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityHor, 0);//GetAxis()获取鼠标的输入
}
else if (axes == RotationAxes.MouseY)//垂直旋转
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;//基于鼠标增加垂直角度
_rotationX = Mathf.Clamp(_rotationX, miniumVert, maximumVert);//将垂直角度限制在最小值和最大值之间
float rotationY = transform.localEulerAngles.y;//保持Y的角度一样(也就是水平没有旋转)
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);//使用存储旋转值创建新的Vector
}
else//水平且垂直旋转
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, miniumVert, maximumVert);
float delta = Input.GetAxis("Mouse X") * sensitivityHor;//旋转变化量
float rotationY = transform.localEulerAngles.y + delta;//使用delta增加旋转角度
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
}
}
第一人称控件
运行效果:键盘WSAD或上下左右,鼠标移动水平高度
//using System.Collections.Generic;
using UnityEngine;
using System.Collections;
public class FPS : MonoBehaviour
{
public float speed = 3.0f;
//观察周围
public enum RotationAxes
{
MouseXAndY = 0,
MouseX = 1,
MouseY = 2
}
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityHor = 9.0f;//旋转速度
public float sensitivityVert = 9.0f;
public float miniumVert = -45.0f;
public float maximumVert = 45.0f;
private float _rotationX = 0;
void Start()
{
Rigidbody body = GetComponent<Rigidbody>();
if (body != null)
body.freezeRotation = true;
}
// Update is called once per frame
void Update()
{
if (axes == RotationAxes.MouseX)//水平旋转
{
transform.Translate(0, Input.GetAxis("Mouse X") * sensitivityHor, 0);//GetAxis()获取鼠标的输入
}
else if (axes == RotationAxes.MouseY)//垂直旋转
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;//基于鼠标增加垂直角度
_rotationX = Mathf.Clamp(_rotationX, miniumVert, maximumVert);//将垂直角度限制在最小值和最大值之间
float rotationY = transform.localEulerAngles.y;//保持Y的角度一样(也就是水平没有旋转)
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);//使用存储旋转值创建新的Vector
}
else//水平且垂直旋转
{
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp(_rotationX, miniumVert, maximumVert);
float delta = Input.GetAxis("Mouse X") * sensitivityHor;//旋转变化量
float rotationY = transform.localEulerAngles.y + delta;//使用delta增加旋转角度
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
}
float deltaX = Input.GetAxis("Horizontal") * speed;
float deltaZ = Input.GetAxis("Vertical") * speed;
transform.Translate(deltaX, 0, deltaZ);
}
}
碰撞检测
问题:如果前面有一堵墙飞机往前会直接穿过去
运行效果:碰到墙壁无法穿过
//using System.Collections.Generic;
using UnityEngine;
using System.Collections;
public class FPS : MonoBehaviour
{
public float speed = 3.0f;
private CharacterController _charController;
void Start()
{
_charController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float deltaX = Input.GetAxis ("Horizontal") * speed;
float deltaZ = Input.GetAxis ("Vertical") * speed;
Vector3 movement = new Vector3 (deltaX, 0, deltaZ);
movement = Vector3.ClampMagnitude (movement, speed);
movement *= Time.deltaTime;
movement = transform.TransformDirection (movement);
_charController.Move (movement);
}
}
重力添加
添加重力gravity就能改为陆地行走,在面板将重力改为0则飞行模式
using System.Collections;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
[AddComponentMenu("Control Script/FPS Input")]
public class FPS : MonoBehaviour
{
public float speed = 6.0f;
public float gravity = -9.8f;
private CharacterController _charController;
// Start is called before the first frame update
void Start()
{
_charController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float deltaX = Input.GetAxis("Horizontal") * speed;
float deltaZ = Input.GetAxis("Vertical") * speed;
Vector3 movement = new Vector3(deltaX, 0, deltaZ);
movement = Vector3.ClampMagnitude(movement, speed);
movement.y = gravity;
movement *= Time.deltaTime;
movement = transform.TransformDirection(movement);
_charController.Move(movement);
}
}