Stage.3 —— 太阳系

13:所以说为什么是hero?
k :干嘛一定要是村民什么的啊
13:是牧师啊!
k :啧~
13:喂。。
k :这种毫无个性的角色定位一定都是那种一上来就领便当的啦
13:游戏还没开始呢怎么就领便当了,话说你这家伙这么看不起牧师,你自己还不是。。。
k :所以啊。。
13:(完全没在听人说话。。。)
k :我们先把太阳系那个做了吧
13:━┳━ ━┳━。。。
k :┳━━ ┳━━ 怎么了?
13:怎么说呢,究竟是习惯了还是已经麻木了呢,我自己都不太清楚了。。。
k :干嘛啦,我又怎么了,我说啊,你是不是也差不多该反省一下自己那边了啊?
13:哈?我?
k :不要每次都指望我的跳跃性思维停下来等你哦?
13:你倒是有自知之明啊。。
k :其实吧,就是那个啦,就好像写博客写到一半的时候突然发现标题写错了,然后就将错就错写下去那种感觉啦
13:这算什么感觉啊!还有别把这种很不妙的东西说出来啊。。
k :很好,那我们赶紧开始吧(打哈欠。。)
13:(一点都不好。。。)|||
k :其实说到底就是简单的旋转而已啦
13:额。。嗯,是吧
k :所以呢
13:嗯
k :你写啊
13:。。。行,我写,你闭嘴吧

//transform.RotateAround( 定点 Vector3, 旋转轴 Vector3, 旋转角度 float)
Vector3 parent_position = transform.parent;
transform.RotateAround(parent_position, Vector3. Y, speed * Time. deltaTime);

这样就可以实现让子物体围绕其上的物体旋转了,毕竟我们肯定是要把行星放到恒星下面的嘛
k :唔。。。
13:(打代码)
k :嗯。。。
13:。。。(叹气),算了,刚刚开玩笑的,你有什么就说啊
k :不对
13:啊?
k :对啊,行星不是他们所在的平面不是不一样吗,这样子的话不是都是在同一个平行面上转吗
13:但是我们一开始可以初始化他们的空间位置不在同一个平面,然后。。。额,好像不对,这样等下虽然是不在一个平面了但是不会绕太阳转而是变成绕太阳所在的垂直轴线转了。。。
k :只要绕跟行星太阳的连线垂直的那条轴线旋转就好了吧
13:也是呢,那要。。。
k :这样就好吧,我们在太阳的脚本上对行星的位置初始化

    //太阳的脚本
    void Start () {
        //获得所有行星
        Transform[] children = this. gameObject.GetComponentsInChildren<Transform> ();
        //太阳跳过
        int i = 1;
        foreach(Transform child in children) {
            //月球也要跳过
            if (child.name == "moon")
                continue;
            //随机y值
            float y = (float)Random.Range (0, 5);
            //和太阳的距离递增 radius = 10 * i,在这个范围内随机生成一个z值
            float z = (float)Random.Range (0, 10 * i);
            //根据半径和z值计算出x值
            float x = Mathf.Sqrt (100 * i * i - z * z);
            child.transform. position = new Vector3 (x, y, z);
            i++;
        }
    }

然后只要根据中心对称和相似性计算出旋转轴就好了,简单画一下图设一下变量就可以得到从物体位置到旋转轴的转化了

//行星的脚本
int z;
int y;
int x;
//向量投影到x,z平面上的模长
int radius_plane;
void Start () {
    //如果是地球,初始化月球位置
    if (this.transform. name == "Earth") {
        Transform[] earth_moon_system = this.transform. GetComponentsInChildren<Transform> ();
        earth_moon_system [1].transform. position = new Vector3 (1, 0, 1);
    }
    //获得
    this.z = transform. position. z;
    this.y = transform. position. y;
    this.x = transform. position. x;
    this.radius_plane = Mathf. Sqrt (x * x + z * z);
}
void Update () {
    this.transform. RotateAround
    (this.transform.parent.position,
    //利用垂直,根据相似性得到旋转轴,旋转点在(0,0,0)方便想象
    new Vector3 (Mathf.Abs(y) * z / radius_plane * -1,
                radius_plane,
                Mathf.Abs(y) * x / radius_plane * -1 ),
    Time. deltaTime * speed_public);
    //顺便自转一下
    this.transform. Rotate (Vector3. up * Time. deltaTime * speed_self);
}

这样就行了呢
13:(明明是笨蛋,但就是数学好。。。)
k :还差呢
13:诶?八大行星不是都在这里了吗?而且冥王星应该已经out了吧。。。
这里写图片描述
k :嗯?不是还有一个外面的一圈吗?
13:哈?
k :柯伊伯陨石带
13:说吧,从哪个电视节目里听来的
k :cctv9
13:就知道。。。嘛,其实也不难啦,用一个死循环放在协程(Coroutine)里去跑就行了
k :欸?携。。携程?跑高铁吗
13:(写下)
k :哦
13:哦什么啊,你根本就不懂吧。。。但是讲起来有点难呢,而且我也有点困了呢,你可以看看这个http://dsqiu.iteye.com/blog/2029701
k :emmmm。。。
13:但是我们这里不用太深奥的东西了,其实大概理解为一个协同的进程,就是把我们所要执行的一些可以并行的任务放到另外一个线程中去执行,这就是Coroutine的功能,关键是我们可以在代码的任何一个地方使用它。嘛,具体的话你自己看了,反正我们只需要这样写就够了

//计数
int star_dust_counter = 0;
//IEnumerator一个迭代器
IEnumerator Kuiper_Generator(){
    //看似是死循环,但是 yield return 语句会把控制权交还给主线程
    while(true){
        int type = Random.Range (1, 4);
        //我们在半径100的位置生成陨石圈
        float x = (float)(Random.Range (-1000, 1000) / 10.0);
        float z = Mathf.Sqrt (100 * 100 - x * x) * (star_dust_counter % 2 == 0 ? 1 : -1);
        //克隆预制体
        GameObject star_dust = (GameObject)Instantiate (Resources.Load("Free_Rocks/_prefabs/rock" + type), new Vector3(x, 0, z), Quaternion.identity);
        star_dust.transform.parent = this.transform;
        //同样,预制体挂有与行星相同的脚本,因为他们的行为是一样的
        //获取脚本的速度变量并初始化
        star_dust.GetComponent<PlanetActionController> ().speed_public = (float)Random.Range (5, 10);
        star_dust_counter++;
        //设置数量上限
        if (star_dust_counter == 100)
            yield break;
        yield return star_dust_counter;
    }
}

然后在Start()里面把这句加上去就好了

//开始协程
StartCoroutine (Kuiper_Generator ());

点击,运行~
这里写图片描述
k :喔~
13:还行呢
k :这岩石挺帅的呢
13:还好啦,Assets Store里面可以找到挺多的
k :切,我还以为是你自己做的呢
13:确实不是我做的。。。但是被你这么说很不爽啊
k :那这些是怎么弄的?
13:嗯?哦,这个在网上随便找一张填满整张图片的行星表面的图片就行了,然后保存到当前项目的Asset文件夹里面,然后我们在unity -> Asset 里面直接把图片拖到物体上就好了
k :这么简单呢
13:嗯,就是这样而已
k :那后面的背景呢
13:在Main Camera里添加Component -> Rendering -> Sky Box的组件就好了,然后Custom Skybox选择默认的一个Diffuse就是黑色的了
k :哦~
13:。。怎么发现你一直都在问我呢,感觉好像是在配合你跟别人解说一样感觉很恶心
k :嗯,哪里,谁啊?(棒读)我想你是太累了吧,要记得去神奇宝贝中心休息一下哦
13:原来你知道我很累啊?还有为什么是去。。。
k :那今天就到此为止了!其实我们还可以简单的给一个Sphere添加rigidbody(addForce()给他一个力), trail renderer 就可以做出流星的效果哦!
13:你倒是。。。
k :总有一天我要撕裂这虚假的天空!
13:你到底是哪个片场的!?
- 完
这里写图片描述

猜你喜欢

转载自blog.csdn.net/Lyn_B/article/details/79775113