unity 3d 三、空间与运动

3D游戏编程第三次作业

简答并用程序验证【建议做】

游戏对象运动的本质是什么?

游戏对象运动的本质是游戏对象Position、Rotate、Scale属性数值的变化。

请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)


  • 使用Vector3
 public int xSpeed = 1;  //单位时间x方向的位移量    
 public int ySpeed = 1;  //单位时间y方向的位移量    
 public int T = 1;       //时间
 void Update()
 {
     transform.position += Vector3.right * Time.deltaTime * xSpeed;
     transform.position += Vector3.down * Time.deltaTime * ySpeed * Time.deltaTime * T;
     T++;
 }
  • 使用Transform.Translate
 public int xSpeed = 1;  //单位时间x方向的位移量    
 public int ySpeed = 1;  //单位时间y方向的位移量    
 public int T = 1;       //时间
 void Update()
 {
     transform.Translate(Vector3.right * Time.deltaTime * xSpeed + Vector3.down * Time.deltaTime * ySpeed * Time.deltaTime * T);
     T++;
 }
  • 直接修改transform
 public int speed = 2;

 void Update()
 {
     transform.position += new Vector3(Time.deltaTime * speed, -Time.deltaTime * speed * (2 * transform.position.x + Time.deltaTime * speed), 0);
 }



写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。



仿照如上课堂的练习,我们可以将太阳系的八大行星都列出来,为他们的position赋值,并且为了满足围绕太阳转速不同以及不在同一法平面的要求,我们额外增加一个向量来表示他们的转动方向,并且在执行RotateAround时传入不同的转动周期。代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SolarSystem : MonoBehaviour
{
	public Transform Sun, Mercury, Venus, Earth, Moon, Mars, Jupiter, Saturn, Uranus, Neptune;
    Vector3 vectMercury, vectVenus, vectEarth, vectMoon, vectMars, vectJupiter, vectSaturn, vectUranus, vectNeptune;
    // Start is called before the first frame update
    void Start()
    {
    	// 初始化位置
        Sun.position = Vector3.zero;
        Mercury.position = new Vector3(8, 0, 0);
        Venus.position = new Vector3(10, 0, 0);
        Earth.position = new Vector3(15, 0, 0);
        Moon.position = new Vector3(18, 0, 0);
        Mars.position = new Vector3(24, 0, 0);
        Jupiter.position = new Vector3(34, 0, 0);
        Saturn.position = new Vector3(44, 0, 0);
        Uranus.position = new Vector3(51, 0, 0);
        Neptune.position = new Vector3(55, 0, 0);
        // Pluto.position = new Vector3(58, 0, 0);

        // 初始化方向向量
        vectMercury = new Vector3(3, 11, 0);
        vectVenus = new Vector3(2, 3, 0);
        vectEarth = new Vector3(0, 1, 0);
        vectMoon = Vector3.up;
        vectMars = new Vector3(1, 5, 0);
        vectJupiter = new Vector3(1, 5, 0);
        vectSaturn = new Vector3(1, 9, 0);
        vectUranus = new Vector3(2, 7, 0);
        vectNeptune = new Vector3(1, 5, 0);
        // vectPluto = new Vector3(1, 3, 0);
    }

    // Update is called once per frame
    void Update()
    {
    	// 以向量向太阳做公转
        Mercury.RotateAround(Sun.position, vectMercury, 10 * Time.deltaTime);
        Venus.RotateAround(Sun.position, vectVenus, 30 * Time.deltaTime);
        Earth.RotateAround(Sun.position, vectEarth, 20 * Time.deltaTime);
        Moon.RotateAround(Earth.position, Vector3.up, 359 * Time.deltaTime);
        Mars.RotateAround(Sun.position, vectMars, 60 * Time.deltaTime);
        Jupiter.RotateAround(Sun.position, vectJupiter, 5 * Time.deltaTime);
        Saturn.RotateAround(Sun.position, vectSaturn, 6 * Time.deltaTime);
        Uranus.RotateAround(Sun.position, vectUranus, 35 * Time.deltaTime);
        Neptune.RotateAround(Sun.position, vectNeptune, 10 * Time.deltaTime);
        // Pluto.RotateAround(Sun.position, vectPluto, 20 * Time.deltaTime);

        // 自转速度
        Sun.Rotate(Vector3.up * 10 * Time.deltaTime);
        Mercury.Rotate(Vector3.up * 600 * Time.deltaTime);
        Venus.Rotate(Vector3.up * 400 * Time.deltaTime);
        Earth.Rotate(Vector3.up * 360 * Time.deltaTime);
        Moon.Rotate(Vector3.up * 1000 * Time.deltaTime);
        Mars.Rotate(Vector3.up * 300 * Time.deltaTime);
        Jupiter.Rotate(Vector3.up * 300 * Time.deltaTime);
        Saturn.Rotate(Vector3.up * 200 * Time.deltaTime);
        Uranus.Rotate(Vector3.up * 400 * Time.deltaTime);
        Neptune.Rotate(Vector3.up * 500 * Time.deltaTime);
        // Pluto.Rotate(Vector3.up * 400 * Time.deltaTime);
    }
}

在制作脚本之后,我们需要为脚本制作prefabs:

并且根据不同星球的大小制作不同的属性:

最终程序运行效果如下:

给每个行星加上Trail Renderer之后可以显示轨迹:

特别注意的是,在制作prefabs之后每个星球的颜色基本是看不见的,这是因为unity中默认使用的是平行光源,我们可以在太阳处增加一个range极大的点光源,这样就可以基本看出一个太阳系的特点:

编程实践

思考题【选做】

  • 使用向量与变换,实现并扩展 Tranform 提供的方法,如 Rotate、RotateAround 等

其中position表示物体的位置,rotation表示物体的角度

Rotate:

void Rotate(Transform trans,Vector3 vect,float angle){ 
    var rotations=Quaternion.AngleAxis(angle, vect);
    trans.rotation*=rot;
}

RotateAround:

void RotateAround(Transform trans,Vector3 center,Vector vect,float angle){		
    var rotations=Quaternion.AngleAxis(angle, vect);
    trans.position=(center+(t.position-center)*rotations);
    trans.rotation=t.rotation*rotations;
}
posted @ 2020-10-04 21:15  沐锋丶  阅读(262)  评论(0编辑  收藏  举报