简答并用程序验证
游戏对象运动的本质是什么?
- 通过代码对游戏对象的位置(position)、大小/比例(scale)、欧拉角(eulerAngles)进行改变;其中欧拉角的改变同样可以通过内部旋转变换(rotation)实现,但unity不建议直接修改这个rotation。
- 这里还是说明一下欧拉角变换和内部旋转变化 :
- 欧拉角变化有三个参数(x,y,z),表示对象线绕着X轴旋转角度x,再绕着Y轴旋转角度y,再绕着Z轴旋转角度z以后得到的结果;
- 内部旋转变化有四个参数(θ,x,y,z),表示对象以向量(x,y,z)为轴旋转θ以后得到的结果;
- 这两种变换可以互换;
请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
- 通过改变transform属性position实现抛物线
using System.Collections; using System.Collections.Generic; using UnityEngine; public class parabolaBehaviourScript : MonoBehaviour { public float speed = 10;//物体初速度(标量,方向为angle),可以随便设置 public float launchAngle = 45;//发射角,可以随便设置 public float gravity = -10;//这个代表重力加速度(标量,方向向下),可以随便设置,一般取10左右 private Vector3 Speed;//物体的速度(矢量) private Vector3 gravitySpeed;//物体在重力方向的速度(矢量) private Vector3 distanceWalkedBySpeed;//单位时间内物体在初速读方向上走过的距离(矢量) private Vector3 distanceWalkedVertical = Vector3.zero;//单位时间内物体在重力方向走过的距离(矢量) private float timePassed;//已经过去的时间 private Vector3 currentAngle; // Use this for initialization void Start() { Speed = Quaternion.Euler(new Vector3(0, 0, launchAngle)) * Vector3.right * speed; gravitySpeed = Vector3.zero; } // Update is called once per frame void Update() { gravitySpeed.y = timePassed * gravity; distanceWalkedBySpeed = Speed * Time.deltaTime; distanceWalkedVertical = gravitySpeed * Time.deltaTime; transform.position += distanceWalkedBySpeed + distanceWalkedVertical; } }
- 通过使用translate平移坐标实现抛物线
using System.Collections; using System.Collections.Generic; using UnityEngine; public class parabolaBehaviourScript : MonoBehaviour { public float speed = 10;//物体初速度(标量,方向为angle),可以随便设置 public float launchAngle = 45;//发射角,可以随便设置 public float gravity = -10;//这个代表重力加速度(标量,方向向下),可以随便设置,一般取10左右 private Vector3 Speed;//物体的速度(矢量) private Vector3 gravitySpeed;//物体在重力方向的速度(矢量) private Vector3 distanceWalkedBySpeed;//单位时间内物体在初速读方向上走过的距离(矢量) private Vector3 distanceWalkedVertical = Vector3.zero;//单位时间内物体在重力方向走过的距离(矢量) private float timePassed;//已经过去的时间 private Vector3 currentAngle; // Use this for initialization void Start() { Speed = Quaternion.Euler(new Vector3(0, 0, launchAngle)) * Vector3.right * speed; gravitySpeed = Vector3.zero; } // Update is called once per frame void Update() { timePassed += Time.deltaTime; gravitySpeed.y = timePassed * gravity; distanceWalkedBySpeed = Speed * Time.deltaTime; distanceWalkedVertical = gravitySpeed * Time.deltaTime; transform.Translate(distanceWalkedBySpeed); transform.Translate(distanceWalkedVertical); } }
- 通过使用vector3的方法实现抛物线模拟
using System.Collections; using System.Collections.Generic; using UnityEngine; public class parabolaBehaviourScript : MonoBehaviour { public float speed = 10;//物体初速度(标量,方向为angle),可以随便设置 public float launchAngle = 45;//发射角,可以随便设置 public float gravity = -10;//这个代表重力加速度(标量,方向向下),可以随便设置,一般取10左右 private Vector3 Speed;//物体的速度(矢量) private Vector3 gravitySpeed;//物体在重力方向的速度(矢量) private Vector3 distanceWalkedBySpeed;//单位时间内物体在初速读方向上走过的距离(矢量) private Vector3 distanceWalkedVertical = Vector3.zero;//单位时间内物体在重力方向走过的距离(矢量) private float timePassed;//已经过去的时间 private Vector3 currentAngle; // Use this for initialization void Start() { Speed = Quaternion.Euler(new Vector3(0, 0, launchAngle)) * Vector3.right * speed; gravitySpeed = Vector3.zero; } // Update is called once per frame void Update() { timePassed += Time.deltaTime; gravitySpeed.y = timePassed * gravity; distanceWalkedBySpeed = Speed * timePassed; distanceWalkedVertical = gravitySpeed * timePassed; //Vector3.Project(distanceWalkedBySpeed, distanceWalkedVertical)是distanceWalkedBySpeed在distanceWalkedVertical方向的投影 //Vector3.Project(distanceWalkedBySpeed, distanceWalkedVertical) + distanceWalkedVertical)是最终的竖直方向位移 //Vector3.Project(distanceWalkedBySpeed, new Vector3(1, 0, 0))是distanceWalkedBySpeed在水平方向的投影,最终的水平位移 transform.position = (Vector3.Project(distanceWalkedBySpeed, distanceWalkedVertical) + distanceWalkedVertical) + Vector3.Project(distanceWalkedBySpeed, new Vector3(1, 0, 0)); } }
写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
代码如下:using System.Collections; using System.Collections.Generic; using UnityEngine; public class sunset : MonoBehaviour { public Transform Sun;//太阳 public Transform Mercury;//水星 public Transform Venus;//金星 public Transform Earth;//地球 public Transform Mars;//火星 public Transform Jupiter;//木星 public Transform Saturn;//土星 public Transform Uranus;//天王星 public Transform Neptune;//海王星 public Transform moon;//月球 //注意冥王星是不是太阳系的大行星,所以不在此列 Vector3[] Shaft = new Vector3[8];//题目要求各个星球公转轨道不在同一个平面,所以我们可以设置不同的转轴来达到目的 float[] RevolutionSpeed = { 40, 35, 30, 25, 21, 16, 12, 8 };//题目要求其他星球围绕太阳的转速必须不一样,所以这里设置共转速度,这也是为什么不随机设置公转速度,因为可能有问题(远的行星速度公转反而更快这是不科学的) //这里设置速度原则上离太阳越远公转速度越慢,只要符合这个规则个人认为还过得去 float [] RotationSpeed = new float [8];//行星的自转速度,这里我不知道各个行星自转速度情况,所以随机设置 void Start() { for (int i = 0; i < 8; i++) { //初始化时随机设置转轴 Shaft[i] = new Vector3(Random.Range(1, 1000),Random.Range(1, 1000), 0); //初始化时随机设置自转速度 RotationSpeed[i] = Random.Range(80, 200); } } // Update is called once per frame void Update() { Mercury.RotateAround(Sun.position, Shaft[0], RevolutionSpeed[0] * Time.deltaTime); Mercury.Rotate(Vector3.up * RotationSpeed[0] * Time.deltaTime); Venus.RotateAround(Sun.position, Shaft[1], RevolutionSpeed[1] * Time.deltaTime); Venus.Rotate(Vector3.up * RotationSpeed[1] * Time.deltaTime); Earth.RotateAround(Sun.position, new Vector3(0, 1, 0), RevolutionSpeed[2] * Time.deltaTime);//地球的平面设置为初始平面 Earth.Rotate(Vector3.up * RotationSpeed[2] * Time.deltaTime); Mars.RotateAround(Sun.position, Shaft[3], RevolutionSpeed[3] * Time.deltaTime); Mars.Rotate(Vector3.up * RotationSpeed[3] * Time.deltaTime); Jupiter.RotateAround(Sun.position, Shaft[4], RevolutionSpeed[4] * Time.deltaTime); Jupiter.Rotate(Vector3.up * RotationSpeed[4] * Time.deltaTime); Saturn.RotateAround(Sun.position, Shaft[5], RevolutionSpeed[5] * Time.deltaTime); Saturn.Rotate(Vector3.up * RotationSpeed[5] * Time.deltaTime); Uranus.RotateAround(Sun.position, Shaft[6], RevolutionSpeed[6] * Time.deltaTime); Uranus.Rotate(Vector3.up * RotationSpeed[6] * Time.deltaTime); Neptune.RotateAround(Sun.position, Shaft[7], RevolutionSpeed[7] * Time.deltaTime); Neptune.Rotate(Vector3.up * RotationSpeed[7] * Time.deltaTime); moon.RotateAround(Earth.position, Vector3.up, 120 * Time.deltaTime);//月亮公转速度按照ppt上的 } }
inspector结构:
hierarchy结构:
用到的素材图片:
最终效果:
这里稍加说明一下代码(注释其实已经很清楚了):
题目要求各个星球公转轨道不在同一个平面,所以我们可以设置不同的转轴来达到目的
题目要求其他星球围绕太阳的转速必须不一样,所以在数组RevolutionSpeed中设置公转速度