查看: 3972|回复: 17
收起左侧

[开发经验] Unity做物理弹球游戏

[复制链接]

[开发经验] Unity做物理弹球游戏[复制链接]

五月de麦子 发表于 2017-12-26 09:59:32 [显示全部楼层] |只看大图 回帖奖励 |倒序浏览 |阅读模式 回复:  17 浏览:  3972

大神收下我的膝盖,物理大法好啊,虽然不知道他这些数据哪里来的,但是为了不在错过好妹子,我开始研究物理,并且再Unity中模拟实现【真实弹球游戏】!!
1.场景搭建
因为弹球游戏是一个物理游戏所以代码不会涉及太多,主要是要考虑当小球靠重力掉落,所以整个场景应该时与Z轴不平行的,所我在X轴上旋转了90度,小球发生碰撞时所受弹力作用,这就需要给场景中的物体加上碰撞器,并且添加运动力学组件,并且再运动力学组件上设置静摩擦力和懂摩擦力还有弹力的大小,导入相关素材,搭建场景。
如图:

Unity做物理弹球游戏

Unity做物理弹球游戏

2. 游戏设定
1.小球
本来以为物理游戏球只要受运动力学组件中的弹力作用设置弹力大小就好了,可是实际上,一些高弹力的装置,弹力值调到最大也没有达到我想要的弹力效果,所以我给小球写了个脚本额外给力来增加弹力。代码如下:
[C#] 纯文本查看 复制代码
private Rigidbody rigid;
    [SerializeField]
    private  Transform _rightSuperBounce;
    [SerializeField]
    private Transform _leftSuperBounce;

    private void Awake()
    {
        rigid = GetComponent<Rigidbody>();
    }

    private void OnTriggerEnter(Collider collision)
    {
        if (collision.transform.name == "Die")
        {
            StartCoroutine(Relive());
        }
        if (collision.transform.name == "LeftSuperBounce")
        {
            rigid.AddRelativeForce(-_leftSuperBounce.right * 20, ForceMode.Impulse);
        }
        if (collision.transform.name == "RightSuperBounce")
        {
            rigid.AddRelativeForce(_rightSuperBounce.right * 20, ForceMode.Impulse);
        }
        if (collision.transform.name == "Cylinder")
        {
            rigid.AddRelativeForce(new Vector3(transform.position.x - collision.transform.position.x, transform.position.y - collision.transform.position.y, 0) * 20, ForceMode.Impulse);
        }
    }

    IEnumerator Relive()
    {
        yield return new WaitForSeconds(2);
        transform.position = new Vector3(-9.3f, 0, 0);
    }
}

2.控制器
就是弹球的左右手臂,用来将掉落的小球重新抛回去。
代码如下:
[C#] 纯文本查看 复制代码
[SerializeField][/align][align=left]    private Transform _rightHand;
    [SerializeField]
    private Transform _leftHand;

    private bool _rightHandRotat;
    private bool _leftHandRotat;
    private bool _rightHandRotat;
    private bool _leftHandRotat;


    private void FixedUpdate()
    {
       
        if (Input.GetKeyDown(KeyCode.D))
        {
            _rightHandRotat = true;
        }
        if (Input.GetKeyUp(KeyCode.D))
        {
            _rightHandRotat = false;
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            _leftHandRotat = true;
        }
        if(Input.GetKeyUp(KeyCode.A))
        {
            _leftHandRotat = false;
        }
        if (_rightHandRotat)
        {
            _rightHand.GetComponent<Rigidbody>().AddRelativeForce(transform.up * 10, ForceMode.Impulse);
        }
        else
        {
            _rightHand.GetComponent<Rigidbody>().AddTorque(new Vector3(0, 0, -1) * 1000,ForceMode.Impulse);
        }
        if (_leftHandRotat)
        {
            _leftHand.GetComponent<Rigidbody>().AddRelativeForce(transform.up * 10, ForceMode.Impulse);
        }
        else
        {
            _leftHand.GetComponent<Rigidbody>().AddTorque(new Vector3(0, 0, 1) * 1000);
        }
    }
}

3.发力器
在初始位置给小球一个瞬间力,让小球沿着轨道进入场景当中
代码如下:
[C#] 纯文本查看 复制代码
[SerializeField]
    private Transform _ball;

    private bool _begin = true;

        void FixedUpdate()
    {
        if (_begin)
        {
            if (Input.GetKey(KeyCode.Space))
            {
                if (transform.position.y > -3.5)
                {
                    transform.position -= transform.up * Time.deltaTime;
                }
            }
            if (Input.GetKeyUp(KeyCode.Space))
            {
                _ball.GetComponent<Rigidbody>().AddForce(new Vector3(0, 1, 0) * (float)(-1.55 - transform.position.y) * 100, ForceMode.Impulse);
                _begin = false;
                if (transform.position.y < -1.55)
                {
                    StartCoroutine(Back(Time.deltaTime));
                }
            }
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.transform.name == "Ball")
        {
            _begin = true;
        }
    }

    IEnumerator Back(float time)
    {
        yield return new WaitForSeconds(time);
        transform.position += transform.up * (float)(-1.55 - transform.position.y); 
    }
}
都完成了之后来看看效果吧:

Unity做物理弹球游戏

Unity做物理弹球游戏

第一次做物理游戏对Unity物理引擎也不熟,很多东西都不知道也就上了,感觉坑点很多,比如如何让一个物体沿着固定点旋转,刚开始我用的是transform.RotateAround,每帧改变旋转位置,发现当小球速度快的时候有穿模现象,于是改用扭矩旋转,但是又不知道怎么用扭矩围绕固定点旋转,后面请教人才知道在里面加Hinge Joint组件来增加固定点。后面终于如我所想的样子转起来了但是扭矩的力又不够吧球弹到相应高度······反正一步一坑啊!看着简单要做到模仿真实物理碰撞,感觉还差好远·······还好我能研究,我还想研究·······所有又想法或者有更好方法的小伙伴大家来探讨下呗·······
相关工程素材与代码
游客,如果您要查看本帖隐藏内容请回复

+1
3982°C
17
  • heartstrings
  • heartstrings
  • Hesam1353
  • 星空1989
  • evangel00
过: 他们
因分享而快乐,学习以自强!
heartstrings 发表于 2017-12-26 12:31:02 显示全部楼层
666666666666666666666666666
因分享而快乐,学习以自强!
heartstrings 发表于 2017-12-26 12:31:37 显示全部楼层
6666666666666666
因分享而快乐,学习以自强!
Hesam1353 发表于 2017-12-26 13:27:38 显示全部楼层
good
因分享而快乐,学习以自强!
星空1989 发表于 2017-12-26 13:50:45 显示全部楼层
66666666666666666666666666
因分享而快乐,学习以自强!
evangel00 发表于 2017-12-26 14:32:06 显示全部楼层
~~~666,感谢分享~~~
因分享而快乐,学习以自强!
sd6592558 发表于 2017-12-26 14:54:32 显示全部楼层
~~666,感谢分享~~~
因分享而快乐,学习以自强!
叫我冷场王123 发表于 2017-12-26 15:01:05 显示全部楼层
666666666666666感谢楼主分享
因分享而快乐,学习以自强!
Browns 发表于 2017-12-26 16:49:00 显示全部楼层
不错!看起来很棒啊!!!
因分享而快乐,学习以自强!
Chi_bing 发表于 2017-12-26 20:42:07 显示全部楼层
很棒,学习了~~~~~~~~
因分享而快乐,学习以自强!
qq1186351245 发表于 2017-12-27 13:10:49 显示全部楼层
666666,谢谢谢分享
因分享而快乐,学习以自强!
wq123456 发表于 2017-12-27 16:25:47 显示全部楼层
挺好的,学到了
因分享而快乐,学习以自强!
悠易 发表于 2017-12-29 17:04:09 显示全部楼层
谢谢分享
因分享而快乐,学习以自强!
wm09323 发表于 2017-12-31 16:12:33 显示全部楼层
好棒的分享,谢谢楼主
因分享而快乐,学习以自强!
大发DDDa 发表于 2018-1-9 09:33:06 显示全部楼层
666666666666666666666666666
因分享而快乐,学习以自强!
12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

VR/AR版块|Unity3d|Unreal4|新手报道|小黑屋|站点地图|沪ICP备14023207号-9|【泰斗社区】-专注互联网游戏和应用的开发者平台 ( 沪ICP备14023207号-9 )|网站地图

© 2001-2013 Comsenz Inc.  Powered by Discuz! X3.4

1
QQ