一:创建3D项目
二:导入飞机模型包和地形资源包
三:为飞机模型添加刚体组件
四:飞控脚本实现
创建C#脚本,命名为FightControl.cs,并添加到飞机模型上
双击文件,打开编辑器开始编写,我使用的Visual Studio,一下是原书自带项目实例的脚本文件。
using UnityEngine;
using System.Collections;
public class AirControl : MonoBehaviour
{
private Transform m_transform; //保存Transform实例
public float speed = 50f; //飞机的飞行速度
private float rotationz = 0.0f; //绕Z轴的旋转量
public float rotateSpeed_AxisZ = 45f; //绕Z轴的旋转速度
public float rotateSpeed_AxisY = 20f; //绕Y轴的旋转速度
private float screenWeight; //屏幕宽度
private Vector2 touchPosition; //触摸点坐标
// Use this for initialization
void Start()
{
m_transform = this.transform; //赋值,减少外部代码的调用
this.gameObject.GetComponent<Rigidbody>().useGravity = false; //默认不受重力影响
screenWeight = Screen.width; //获取屏幕宽度
}
// Update is called once per frame
void Update()
{
m_transform.Translate(new Vector3(0, 0, speed / 20 * Time.deltaTime));//向前移动
// 寻找到名称为“propeller”的对象并使其绕Y轴旋转
GameObject.Find("propeller").transform.Rotate(new Vector3(0, 100f, 0));
// 获取飞机对象绕X轴的旋转量
rotationz = this.transform.eulerAngles.z;
//----------------触摸监听开始-----------------//
if (Input.touchCount > 0)
{ //当触摸的数量大于0
for (int i = 0; i < Input.touchCount; i++)
{
Touch touch = Input.touches[i]; //实例化当前触摸点
// 手指在屏幕上没有移动或发生滑动时触发的事件
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
{
// 获取当前触摸点坐标
touchPosition = touch.position;
// 触摸点在屏幕左半侧
if (touchPosition.x < screenWeight / 2)
{
if ((rotationz <= 45 || rotationz >= 315))
{
// 飞机向左倾斜
m_transform.Rotate(new Vector3(0, 0, (Time.deltaTime * rotateSpeed_AxisZ)), Space.Self);
}
// 飞机左转
m_transform.Rotate(new Vector3(0, -Time.deltaTime * 30, 0), Space.World);
}
// 触摸点在屏幕右半侧
else if (touchPosition.x >= screenWeight / 2)
{
if ((rotationz <= 45 || rotationz >= 315))
{
// 飞机向右倾斜
m_transform.Rotate(new Vector3(0, 0, (Time.deltaTime * -rotateSpeed_AxisZ)), Space.Self);
}
// 飞机右转
m_transform.Rotate(new Vector3(0, Time.deltaTime * 30, 0), Space.World);
}
}
// 手指离开屏幕时触发的事件
else if (touch.phase == TouchPhase.Ended)
{
BackToBlance(); //调用恢复平衡状态方法
}
}
}
if (Input.touchCount == 0)
{ //当没有手指触摸屏幕时
BackToBlance(); //调用恢复平衡状态方法
}
//----------------触摸监听结束-----------------//
//判断当前运行平台为Android平台
if (Application.platform == RuntimePlatform.Android)
{
if (Input.GetKeyDown(KeyCode.Home))
{ //触发Hmoe按钮
Application.Quit(); //退出程序
}
if (Input.GetKeyDown(KeyCode.Escape))
{ //触发返回按钮
Application.Quit(); //退出程序
}
}
}
void BackToBlance() //恢复平衡方法
{
if ((rotationz <= 180))
{ //判断如果飞机为右倾状态
if (rotationz - 0 <= 2)
{ //在阈值内轻微晃动
m_transform.Rotate(0, 0, Time.deltaTime * -1);
}
else
{ //快速恢复平衡状态
m_transform.Rotate(0, 0, Time.deltaTime * -40);
}
}
if ((rotationz > 180))
{ //判断如果飞机为左倾状态
if (360 - rotationz <= 2)
{ //在阈值内轻微晃动
m_transform.Rotate(0, 0, Time.deltaTime * 1);
}
else
{ //快速恢复平衡状态
m_transform.Rotate(0, 0, Time.deltaTime * 40);
}
}
}
}
五:摄像机跟随脚本实现
该脚本挂载在主摄像机(Main Camera)上,该脚本是unity标准资源包中自带脚本
创建新的标签
更改飞机模型的标签
根据标签属性在场景中查找游戏对象
// 寻找标签为“AirPlane”的游戏对象并设置为要跟随的目标对象
target = GameObject.FindWithTag("AirPlane");
摄像机跟随脚本内容如下:
using UnityEngine;
using System.Collections;
public class SmoothFollow : MonoBehaviour
{
private GameObject target; //所要跟随的目标对象
public float distance = 10.0f; //与目标对象的距离
public float height = 5.0f; //与目标对象的高度差
public float heightDamping = 2.0f; //高度变化中的阻尼参数
public float rotationDamping = 3.0f;//绕y轴的旋转中的阻尼参数
void Start()
{
// 寻找标签为“AirPlane”的游戏对象并设置为要跟随的目标对象
target = GameObject.FindWithTag("AirPlane");
}
void LateUpdate()
{ // 如果目标对象不存在将跳出方法
if (!target)
return;
// 摄像机期望的的旋转角度计高度
float wantedRotationAngle = target.transform.eulerAngles.y;
float wantedHeight = target.transform.position.y + height;
// 摄像机当前的旋转角度及高度
float currentRotationAngle = transform.eulerAngles.y;
float currentHeight = transform.position.y;
// 计算摄像机绕y轴的旋转中的阻尼
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
// 计算摄像机高度变化中的阻尼
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
// 转换成旋转角度
var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
// 摄像机距离目标背后的距离
transform.position = target.transform.position;
transform.position -= currentRotation * Vector3.forward * distance;
// 设置摄像机的高度
transform.position = new Vector3(transform.position.x, currentHeight, transform.position.z); ;
// 摄像机一直注视目标
transform.LookAt(target.transform);
}
}
六:最终效果如下