Unity中行星和恒星的旋转——Rotate和RotateAround

Posted Z_hongli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity中行星和恒星的旋转——Rotate和RotateAround相关的知识,希望对你有一定的参考价值。

实现效果

一、与之相关的两种旋转方式

1.Rotate

Unity中文文档对于transform.Rotate说明链接:点击进入,用法有很多种,想查看全部用法可以进入链接。

描述:使用 Transform.Rotate 以各种方式旋转 GameObjects。通常以欧拉角而不是四元数提供旋转
自转用法:

    //public来定义可以在外部修改,Unity会以外部编辑器的参数作为游戏运行时的参数
    public float rotate_speed = 30f;//设置旋转速度

    void Update()
    {
        transform.Rotate(Vector3.down * rotate_speed * Time.deltaTime); //物体自转
        //Vector3=Vector(0,1,0)是一个向上的向量,代表Y轴
        //Time.deltaTime每帧调用一次
    }

我们可以利用这个代码来实现物体的自转,通过

2.transform.RotateAround

Unity中文文档相关说明:

不难理解,RotateAround是专门为物体围绕物体旋转而生的函数,内置参数分别为旋转目标的坐标、旋转的轴向、旋转的速度

二、行星案例的实现

Step1:我们先在场景中创建一个球体,并将它放大作为被环绕的恒星(我这里自己上了贴图)


为其添加脚本,并将脚本拖拽至创建的球体上:

    //public来定义可以在外部修改,Unity会以外部编辑器的参数作为游戏运行时的参数
    public float rotate_speed = 30f;//设置旋转速度

    void Update()
    {
        transform.Rotate(Vector3.down * rotate_speed * Time.deltaTime); //物体自转
        //Vector3=Vector(0,1,0)是一个向上的向量,代表Y轴
        //Time.deltaTime每帧调用一次
    }

运行游戏可以发现自转效果已经完成:

Step2:制作环绕它的行星;我们创建一个比恒星小一些的球体,将它水平拖拽到离恒星有一定距离的位置


为其添加脚本,并将脚本拖拽至创建的球体上:

    public float rotate_speed = 60f; //自转速度
    public float around_speed = 60f; //公转环绕速度
    public Transform around_aim; //设置公转目标

    void Start()
    {
       
    }

    void Update()
    {
        //行星自转 
        transform.Rotate(Vector3.down * rotate_speed * Time.deltaTime);
        //行星公转
        transform.RotateAround(around_aim.position, Vector3.up ,around_speed * Time.deltaTime);
    }

代码编写完成后将公转目标拖拽至脚本中:(我这里是最终脚本)

点击运行游戏我们可以发现恒星自转,卫星自转加公转,并且我们可以修改脚本参数来修改旋转的速度:

Step3:再创建一个比行星小的球体,并将其移动到行星的周围


在Assets下创建一个文件,并将其命名为:Resources,一定要命名为Resources,大小写都不能错,因为我们等会要从Resources中加载预制体;再在Resources下创建一个文件夹命名为Prefab,大小写也不能错,将创建出来的卫星拖拽至文件夹中,这时我们发现上面的面板中卫星边蓝了,这就说明预制体制作成功,再把场景中预制体删掉,这并不影响我们对于删掉预制体的使用,我们可以在Prefab文件夹下再将其拖拽出来。

Step4:卫星的环绕与摧毁

思路:在行星的周围生成一个卫星并使其成为行星的子物体随着行星一起移动,在生成卫星的一段时间后将其摧毁,再过一段时间再生成
step1:卫星的生成:(这里的pfb、prefabInstance是GameObject类型的全局变量,如果是局部变量不方便后面的摧毁),关键代码如下

                pfb = Resources.Load("Prefab/satellite") as GameObject;
                //加载在Resource文件夹下Prefab文件夹下的statellite预制体 这里要求预制体的名称和代码中的命名一样 最好英文
                //这也是为什么要固定命名的原因
                prefabInstance = Instantiate(pfb,this.transform.position + vec ,Quaternion.identity);
                //生成一个预制体,预制体为pfb,生成的位置是这个脚本挂载的物体的位置(行星位置)+向X轴偏离的位置,默认角度(无偏转)
                prefabInstance.transform.parent = this.transform;
                //将卫星设置为行星的子物体

step2:卫星环绕行星旋转,关键代码如下

prefabInstance.transform.RotateAround(this.transform.position, Vector3.up, around_speed * Time.deltaTime);

step3:卫星旋转后销毁

Destroy(prefabInstance);

Step5:脚本的完善(完整的行星脚本)

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

public class Planetaryrotation : MonoBehaviour
{
    public float around_speed = 60f;//控制环绕速度
    public float rotate_speed = 60f;//控制自转速度
    public Transform around_aim; //设置行星环绕目标

    public float time_1 = 3;//卫星出现间隔
    public float time_2 = 3;//卫星存留时间
    public float appear_time = 0; //计时参数
    bool isappear = true;//判断卫星是否消失

    private GameObject pfb;//需要加载的预制体
    private GameObject prefabInstance;//生成预制体的实例化
    public float distance = 10;//控制行星与卫星的间距

    Vector3 vec = new Vector3(15, 0, 0);//设置一个三维变量用来做行星与卫星间距离的参数
    Transform tra;//设置一个转换变量类型的载体,position不能和vect相加

    int num = 0;//控制卫星数量的参数
    //start函数只执行一次(游戏开始时)
    void Start()
    {
        Vector3 vec = new Vector3(distance, 0, 0);//distance控制距离
        tra.position = vec;
    }
   //每帧执行一次
    void Update()
    {
        
        Vector3 vec = new Vector3(distance, 0, 0);
        //行星自转
        transform.Rotate(Vector3.down * rotate_speed * Time.deltaTime);
        //行星公转
        transform.RotateAround(around_aim.position, Vector3.up ,around_speed * Time.deltaTime);

        //控制卫星出现的时间
        appear_time = appear_time + Time.deltaTime; //计时器
        if (appear_time > time_1)//判断是否生成卫星
        {
            isappear = false;
            if(isappear==false&&num!=1)//判断是否已经生成卫星,没有生成卫星便生成卫星
            {
                pfb = Resources.Load("Prefab/satellite") as GameObject;
                prefabInstance = Instantiate(pfb,transform.position + vec ,Quaternion.identity);
                prefabInstance.transform.parent = this.transform;
                isappear = true;
                num = 1;
            }
            if(num==1)//如果生成卫星,则让它围绕行星旋转
            {
               prefabInstance.transform.RotateAround(this.transform.position, Vector3.up, around_speed * Time.deltaTime);
            }

            if (appear_time>time_1+time_2)//判断是否达到存在的时间,达到后摧毁自己,并且将所有相关数据设置为初始化
            {
                appear_time = 0;
                Destroy(prefabInstance);
                num = 0;
            }   
        }
    }
}

Step6:卫星的代码(完整)

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

public class Satelliterotation : MonoBehaviour
{
    public float around_speed = 60f;
    private Transform around_aim;
    public string aim_name;


    void Start()
    {
        GameObject container = GameObject.Find(aim_name);//在场景中找到与aim_name一样名称的物体,将其实例化给container
        //这里是行星的名称,需要在外部手动输入
        around_aim.transform.position = container.transform.position;
    }


    void Update()
    {
        //卫星环绕
        transform.RotateAround(around_aim.position, Vector3.up, around_speed * Time.deltaTime);

    }
}


一切准备就绪后运行游戏:

三、添加多个行星

step1.CtrlD赋值一个行星,将其名称修改为与第一个行星名称相同

因为卫星是按名称来找行星的,再将其位置拖拽开来,调整其参数

step2:运行效果

以上是关于Unity中行星和恒星的旋转——Rotate和RotateAround的主要内容,如果未能解决你的问题,请参考以下文章

unity使用localEulerAngles,rotation和Rotate进行旋转的区别

Unity脚本-Rotate旋转相关知识点

保持轨道椭圆的距离

模拟恒星的引力?

Unity2D 小行星风格游戏

unity中的旋转