Unity3D学习笔记——第二次作业

11 篇文章 0 订阅
6 篇文章 0 订阅

空间与运动章节作业

1、简答并用程序验证

  • 游戏对象运动的本质是什么?
          答:游戏对象的运动,实质上是游戏对象相对于原点位置的改变,或者相对于其他游戏对象位置的改变,通过transform组件中的position属性数值的改变,可实现游戏对象的运动。
  • 请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
          答:实现物体移动的方法有许多种。在这里,我用了三种方法来实现物体的抛物线运动(我所理解的抛物线,其实就是二次函数的图像,希望没理解错),如下:
    第一种:直接改变物体transform组件的position属性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Parabola : MonoBehaviour {
    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        float x = this.transform.position.x;
        //实现物体沿抛物线-0.2x * (x - 20)运动
        this.transform.position = new Vector3(x + 1.0f * Time.deltaTime,-0.2f * x * (x - 20), 0);

    }

}

第二种:利用transform的translate方法,分别实现物体在x轴方向上和y轴方向上的移动,通过两个方向运动的合成达到抛物线运动的效果。

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

public class ParabolaByTM : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        float x = this.transform.position.x;
        //物体在x轴方向的移动
        this.transform.Translate(Vector3.right * Time.deltaTime * 5);
        //物体在y轴方向的移动
        this.transform.Translate(Vector3.up * Time.deltaTime * (-0.5f * x + 10));
    }
}

第三种:利用物体的rigidbody组件,通过rigidbody组件的MovePosition方法实现物体的抛物线运动(这里为了方便观察,把物体的重力关了)

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

public class ParabolaByRB : MonoBehaviour {
    private Rigidbody rigidbody;
    // Use this for initialization
    void Start () {
        rigidbody = this.gameObject.AddComponent<Rigidbody>();
        rigidbody.useGravity = false;
       // this.transform.position = new Vector3(0, 5, 0);
    }

    // Update is called once per frame
    void Update () {
        float x = this.transform.position.x;
        //物体移动的速度, -x + 10用于处理y轴上的速度
        Vector3 speed = new Vector3(3, -x + 10, 0);
        rigidbody.MovePosition(transform.position + speed * Time.deltaTime);
    }
}

此外,用Vector3的MoveTowards方法也可以实现物体的移动。

  • 写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
          刚开始弄这个太阳系模拟的时候,是想着按照网上给出的真实比例数据来弄的,后来,弄出来之后,发现,看起来很辛苦,毕竟太阳太大,行星之间的比例相差也很大,然后嘛,它们的公转半径也是相差那么大,摄像机的位置远了,一些行星就小的像一个点,看不清楚,摄像机的位置离太阳近了,又看不清全部行星。最后,就决定,还是不按照真实比例来了,就这么自己编一点数据上去改变他们的比例吧,看起来能看清就行,还有就是,考虑到行星的卫星确实太小了,加上去,也根本看不清楚,所以,就没有弄地月系,其他行星的卫星也没有加上去。然后就是,为了观察方便,也提供了三个视角(近看、远看、俯视)。
    下面看看效果吧:
    全景图
    远看
    近看
    俯视

    虽然是在太阳内部放了一个point light,但是,这些光照到行星表明上时,还是不能把上面的图案给很好的显示出来,可能是因为,光的颜色用的是太阳的颜色吧,用白色的话应该能更好的显现出来。另外,太阳本身发亮这个,用了Glow11这个package。
    具体代码如下:

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

public class SSDirector : System.Object {
    //singlton instance
    private static SSDirector _instance;

    public IScenesController currentScenceController { get; set; }

    public static SSDirector getInstance()
    {
        if(_instance == null)
        {
            _instance = new SSDirector();
        }
        return _instance;
    }

    public int getFPS()
    {
        return Application.targetFrameRate;
    }

    public void setFPS(int fps)
    {
        Application.targetFrameRate = fps;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IScenesController
{
    void LoadResources();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Controller : MonoBehaviour, IScenesController {
    private Transform[] planets = new Transform[8];
    private string[] planets_name = { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune" };
    //private GUITexture background;
    //public Texture2D bg;

    private GameObject ca_0;
    private GameObject ca_1;
    private GameObject ca_2;

    //行星的初始位置,其实也可以看作是公转半径比例啦
    Vector3[] position =
    {
        new Vector3(6, 0, 0),
        new Vector3(10, 0, 0),
        new Vector3(14, 0, 0),
        new Vector3(23, 0, 0),
        new Vector3(38, 0, 0),
        new Vector3(53, 0, 0),
        new Vector3(77, 0, 0),
        new Vector3(90, 0, 0)
    };
    //各行星的公转法平面倾角
    Vector3[] includedAngle = {
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*7)),
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*3.4f)),
        new Vector3 (0, 1, 0),
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*1.9f)),
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*1.3f)),
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*2.5f)),
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*0.8f)),
        new Vector3 (0, 1, Mathf.Tan(Mathf.PI/180*1.8f)),
    };
    //公转速率和自转速率。公转的胡乱编的,自转倒是比较真实
    float[] gongZhuan = { 40.0f, 16.0f, 10.0f, 8.0f, 6.0f, 8.0f, 5.0f, 6.0f };
    float[] ziZhuan = { 6.1f, -1.5f, 360f, 350f, 878f, 844.5f, -500.5f, 540.5f };

    Transform Sun;//太阳组件,作为所有行星的父亲
    //两个背景。至于为什么两个,就为了多个视角,然后,技术不够,只能用这种方法来实现背景
    Transform background1;
    Transform background2;

    void Awake()
    {
        SSDirector director = SSDirector.getInstance();
        director.setFPS(60);
        director.currentScenceController = this;
        director.currentScenceController.LoadResources();

    }

    Transform createTransform(Vector3 position, string name)
    {
        Transform transform = Instantiate<Transform>(Resources.Load<Transform>("prefabs/" + name), position, Quaternion.identity);
        return transform;
    }

    public void LoadResources()
    {
        Sun = createTransform(Vector3.zero, "Sun");
        Sun.name = "Sun";
        background1 = createTransform(new Vector3(0, -100, 500), "background");
        background1.name = "Background";
        background1.localScale += new Vector3(2000, 1000, 100);

        background2 = createTransform(new Vector3(0, -500, 0), "background");
        background2.name = "tBackground";
        background2.localScale += new Vector3(2000, 2, 2000);

        for (int i = 0; i < 8; i++)
        {
            planets[i] = createTransform(position[i], planets_name[i]);
            planets[i].transform.parent = Sun.transform;
            planets[i].name = planets_name[i];
            //用来加尾巴的。不过,有一些属性我试过改了,呈现不出来,就干脆,原始这样子吧
            TrailRenderer trail = planets[i].gameObject.AddComponent<TrailRenderer>();
            trail.startWidth = 0.1f;
        }
    }

    // Use this for initialization
    void Start () {
        ca_0 = GameObject.Find("Camera");
        ca_0.SetActive(true);
        ca_1 = GameObject.Find("Camera1");
        ca_1.SetActive(false);
        ca_2 = GameObject.Find("Camera2");
        ca_2.SetActive(false);
    }

    // Update is called once per frame
    void Update () {
        for(int i = 0; i < 8; i++)
        {
            planets[i].RotateAround(Sun.position, includedAngle[i], gongZhuan[i] * Time.deltaTime);
            planets[i].Rotate(Vector3.up * ziZhuan[i] * Time.deltaTime);
        }
        //三个视角。C是近处,F是远处,R是俯视
        if(Input.GetKeyDown(KeyCode.C))
        {
            ca_0.SetActive(false);
            ca_1.SetActive(true);
            ca_2.SetActive(false);
        }
        if(Input.GetKeyDown(KeyCode.F))
        {
            ca_1.SetActive(false);
            ca_0.SetActive(true);
            ca_2.SetActive(false);
        }
        if(Input.GetKeyDown(KeyCode.R))
        {
            ca_2.SetActive(true);
            ca_1.SetActive(false);
            ca_0.SetActive(false);
        }
    }
    void OnGUI()
    {
        GUIStyle fStyle = new GUIStyle();
        fStyle.fontSize = 40;
        fStyle.normal.textColor = Color.red;//红色比较容易看清
        GUI.Label(new Rect(0, 0, 200, 50), "视角:C为近看,F为远看,R为俯视", fStyle);
    }
}

关于太阳系的模拟仿真具体实现,可以参考我的另一个博客

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值