当前位置:   article > 正文

Unity实现Angry Bird弹弓发射功能_unity prevvelocity

unity prevvelocity

首先声明,Unity版本为5.4.4

这篇主要是针对Unity官网上的一个视频教程,功能就是实现一下Angry Bird中弹弓发射的功能

先去Asset Store上下载2D Sprites Pack素材包,导入到Unity中

这里写图片描述


下面开始搭建场景:

1.将相机设为正交投影

2.在导入的素材中找到背景并拖到Hierarchy中改名为BackGround

这里写图片描述

3.在素材中找到地面拖到Hierarchy中并改名为Grass

这里写图片描述

4.新建一个空物体改名为Ground,多复制几个Grass并在Scene下摆放到适当的位置,调整背景的长度

这里写图片描述

5.给Ground添加Edge Collider2D并点击Edit Collider调整点的位置使线平行地面且端点位于背景左右

这里写图片描述

6.在素材中找到弹弓(是俩张图,把1作为0的子物体)拖到Hierarchy上并改名

这里写图片描述

这里写图片描述

7.在素材中找到投射物并拖到Hierarchy上改名为Asteroid

这里写图片描述

8.在Scene视图中摆放合适位置

这里写图片描述

9.设置Sorting Layer,随便点击场景中的图片,在Sorting Layer上点击Add Sorting Layer,新建ForeGround

这里写图片描述

10.BackGround设置为Default层,所有的Grass设置为ForeGround层order in layer为0,CatapultSprite设置为ForeGround层,order in layer为0,CatapultSprite_1设置为ForeGround层,order in layer为4,Asteroid设置为ForeGround层,order in layer为2

11.在素材中找到木板拖到场景中,并复制多个,怎么摆放都行,并且添加Box Collider2D和Rigidbody2D

这里写图片描述

这里写图片描述


下面开始实现功能

1.给Asteroid添加Circle Collider2D和Rigidbody2D,新建一个 Physics2D Material改名为HighFriction

这里写图片描述

2.新建一个Material命名为Band

这里写图片描述

3.给CatapultSprite添加Rigidbody2D并勾选Is Kinematic,分别给CatapultSprite和CatapultSprite_1添加Line Renderer,把Band分别拖到Line Renderer的Materials上

这里写图片描述

4.给Asteroid添加Spring Joint2D,把CatapultSprite拖拽到Spring Joint2D上的Connected Rigid Body上

这里写图片描述

新建C#脚本ProjectileDragging并拖到Asteroid上

using UnityEngine;
using System.Collections;

public class ProjectileDragging : MonoBehaviour {

    public float maxStretch = 3.0f;//拉伸长度
    public LineRenderer catapultLineFront;//弹弓皮筋前面
    public LineRenderer catapultLineBack;//弹弓皮筋后面

    private SpringJoint2D spring;//弹簧铰链
    private Transform catapult;//弹弓
    private Ray leftCatapultTpProjectile;//用来获取皮筋与投射物接触点的位置
    private Ray rayToMouse;//用来限制物体的位置
    private float maxStretchSql;//拉伸长度的平方
    private Rigidbody2D rb;//刚体
    private CircleCollider2D circle;//圆形碰撞器
    private float circleRadius;//圆形碰撞器半径
    private bool clickedOn;//判断是否是鼠标按下中
    private Vector2 prevVelocity;//发射出去的速度

    void Awake(){
        spring = GetComponent<SpringJoint2D> ();
        rb = GetComponent<Rigidbody2D> ();
        circle = GetComponent<CircleCollider2D> ();
        catapult = spring.connectedBody.transform;
    }

    // Use this for initialization
    void Start () {
        LineRendererSetUp ();
        rayToMouse = new Ray (catapult.position,Vector3.zero);
        leftCatapultTpProjectile = new Ray (catapultLineFront.transform.position,Vector3.zero);
        maxStretchSql = maxStretch * maxStretch;
        circleRadius = circle.radius;
    }

    // Update is called once per frame
    void Update () {
        if (clickedOn)
            Dragging ();
        if (spring != null) {//如果弹簧铰链不为空
            if (!rb.isKinematic && prevVelocity.sqrMagnitude > rb.velocity.sqrMagnitude) {//如果投射物可以受力,且投射速度大于物体自身速度
                Destroy (spring);//脱离铰链
                rb.velocity = prevVelocity;//投射
            }
            if (!clickedOn)
                prevVelocity = rb.velocity;//如果拖拽完成,投射速度等于物体自身的速度

            LineRendererUpdate ();//更新弹弓皮筋
        } else {
            catapultLineFront.enabled = false;
            catapultLineBack.enabled = false;
        }
    }

    private void LineRendererSetUp(){//初始弹弓皮筋
        catapultLineFront.SetPosition (0,catapultLineFront.transform.position);//设置皮筋与弹弓相连的点的位置
        catapultLineBack.SetPosition (0,catapultLineBack.transform.position);
        catapultLineFront.sortingLayerName = "ForeGround";//设置皮筋的渲染层
        catapultLineBack.sortingLayerName = "ForeGround";
        catapultLineFront.sortingOrder = 3;//设置同一层的渲染顺序
        catapultLineBack.sortingOrder = 1;
    }

    void OnMouseDown(){
        spring.enabled = false;//拖拽过程中,弹簧铰链失效
        clickedOn = true;//拖拽中
    }

    void OnMouseUp(){
        spring.enabled = true;//拖拽完后,恢复铰链
        rb.isKinematic = false;//拖拽完后,使投射物受力
        clickedOn = false;
    }

    private void Dragging (){//拖拽中持续更新物体位置
        Vector3 mouseWordPoint = (Camera.main.ScreenToWorldPoint (Input.mousePosition));
        Vector2 catapultToMouse = mouseWordPoint - catapult.position;
        if (catapultToMouse.sqrMagnitude > maxStretchSql) {//限制拖拽长度
            rayToMouse.direction = catapultToMouse;
            mouseWordPoint = rayToMouse.GetPoint (maxStretch);//在射线的方向上找一个距离射线源点maxStretch的点
        }
        mouseWordPoint.z = 0;
        transform.position = mouseWordPoint;
    }

    private void LineRendererUpdate(){//更新弹弓皮筋
        Vector2 catapultToProjectile = transform.position-catapultLineFront.transform.position;
        leftCatapultTpProjectile.direction = catapultToProjectile;
        Vector3 holdPoint = leftCatapultTpProjectile.GetPoint (catapultToProjectile.magnitude+circleRadius);
        catapultLineFront.SetPosition (1,holdPoint);
        catapultLineBack.SetPosition (1,holdPoint);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

这里写图片描述

现在就已经可以投射了,但是相机是不动的

新建C#脚本ProjectileFollow并加到相机上

using UnityEngine;
using System.Collections;

public class ProjectileFollow : MonoBehaviour {

    public Transform projectile;//投射物
    public Transform farLeft;//相机左边界
    public Transform farRight;//相机右边界

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        Vector3 newPosition = transform.position;
        newPosition.x = projectile.position.x;
        newPosition.x = Mathf.Clamp (newPosition.x,farLeft.position.x,farRight.position.x);//限定相机的位置
        transform.position = newPosition;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在场景中新建三个空物体分别为,Boundary,Left,Right,且Left,Right为Boundary的子物体,修改Left,Right的tag图标(容易区分),在Scene视图中摆好位置

这里写图片描述
这里写图片描述

这里写图片描述

现在基本上完成了

最后加一个游戏重置的功能

在场景中新建一个空物体叫BoundaryCollider,并添加Box Collider2D,调整大小使它将整个场景包起来

这里写图片描述

这里需要注意一点,我们把BoundaryCollider的z坐标设为了1,只要不是0就行,原因是如果设为0有时鼠标会点在BoundaryCollider上,Asteroid就点不到了,虽然BoundaryCollider的z设为了1但是还是可以触发碰撞

最后新建C#脚本Resetter并挂到BoundaryCollider上

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class Resetter : MonoBehaviour {

    public Rigidbody2D projectile;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown (KeyCode.R))
            ReSet ();
    }

    void OnTriggerExit2D(Collider2D col){
        if (col.GetComponent<Rigidbody2D> () == projectile)
            ReSet ();
    }

    private void ReSet(){
        SceneManager.LoadScene (SceneManager.GetActiveScene().name);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

好,完事!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/611667
推荐阅读
相关标签
  

闽ICP备14008679号