Unity經典游戲教程之:雪人兄弟


版權聲明:

  • 本文原創發布於博客園"優夢創客"的博客空間(網址:http://www.cnblogs.com/raymondking123/)以及微信公眾號"優夢創客"(微信號:unitymaker)
  • 您可以自由轉載,但必須加入完整的版權聲明!

雪人兄弟游戲開發過程:

場景搭建

1.將Map地圖拖入場景,

9Fqek4.png

2.創建一個ground空對象給這個對象添加一些Collider 2D 組件,把這些Collide2D覆蓋到地圖可以行走的地方,創建以個wall空對象給這個對象添加兩個Collider 2D組件,把這兩個 Collide2D 覆蓋到地圖的兩側。

9FOKL6.jpg

創建主角

1.創建hero對象給其一張主角的圖片精靈,給hero對象添加Rigidbody2D和Collider 2D組件使其可以進行物理運動和碰撞行為;

9FO2yq.png

2. 創建動畫控制器,編輯一些主角行為的的動畫,再用動畫控制器進行控制;

9FXxuq.jpg

3. 添加HeroMove腳本,通過編輯代碼使主角可以移動和跳躍;

//Update時通過射線檢測判斷是否可以跳躍:

RaycastHit2D hit = Physics2D.Linecast(this.transform.position, t.position, 1 << LayerMask.NameToLayer("ground"));
        //Debug.DrawLine(this.transform.position, t.position);// t.position
        //print((bool)hit);
        if (Input.GetButtonDown("Jump") && hit)
        {
            jump = true;
        }

···
//FixedUpdate

        bool speed = false; //觸發動畫的布爾變量

        float h = Input.GetAxis("Horizontal");
        if (h != 0)
        {
            speed = true;
        }
        Vector2 force = new Vector2(h * moveForce, 0);
        //限制移動速度
        if (Mathf.Abs(rb.velocity.x) < maxSpeed)
        {
           
            GetComponent<Animator>().SetBool("Speed", speed);
            rb.AddForce(force);
        }
        if (Mathf.Abs(rb.velocity.x) >= maxSpeed)
        {
            rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * maxSpeed, rb.velocity.y);
        }
        //動畫方向轉變
        if (h < 0)
        {
            var s = this.transform.localScale;
            s.x = Mathf.Abs(-s.x);
            this.transform.localScale = s;
        }
        else if (h > 0)
        {
            var s = this.transform.localScale;
            s.x = -Mathf.Abs(-s.x);
            this.transform.localScale = s;
        }
        //跳躍
        if (jump)
        {

            GetComponent<Animator>().SetTrigger("jump");

            rb.AddForce(Vector2.up * jumpForce);
            jump = false;
        }
        

4.讓主角可以發射子彈:

1. 制作子彈預制體 ,

9Fb0wF.png

2.給hero添加一個子節點Gun作為生成子彈的點,並添加腳本控制子彈的發射和行為。

void Update () {
		if (Input.GetButtonDown("Fire1"))
		{
			this.transform.parent.gameObject.GetComponent<Animator>().SetTrigger("Shoot");
			var rocket = Instantiate(rocketPrefab);
			rocket.transform.position = this.transform.position;
			if (this.transform.parent.localScale.x > 0)
			{
				rocket.transform.rotation = Quaternion.Euler(0, 0, 0);
				rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(speed, 0);
			}
			else
			{
				rocket.transform.rotation = Quaternion.Euler(0, 0, 180);
				rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(-speed, 0);
			}
		}
	}

創建敵人:

1.創建一個monsters空對象為了確定敵人生成的位置:

2. 創建monster對象給其一張敵人的圖片精靈,給monster對象添加Rigidbody2D和Collider2D組件使其可以進行物理運動和碰撞行為,並把它做成預制體。

9FjLdK.png

3. 添加Monster腳本,通過編輯代碼使敵人可以移動和跳躍;

public class Monster : MonoBehaviour
{
    // public float speed = 3; 

    private float MonsterMoveForce = 0.8f;  //速度
    //private float MonsterMaxSpeed = 0.5f;     //限制速度

    public float monsterJumpForce = 600f; //= 2.8f;
    private bool monsterJump = false;

    private Transform topCheck;
    private Transform frontCheck;
    private Transform downCheck;

    int h;
    private int hp = 1;

    public GameObject snowball;

    public void Start()
    {

        topCheck = transform.Find("topCheck");
        frontCheck = transform.Find("frontCheck");
        downCheck = transform.Find("DownCheck");

    }
    public void Update()
    {
        if (hp <= 0)
        {

            Vector2 s = this.transform.position;
            hp = 0;
            Destroy(this.gameObject);
            GameObject g = Instantiate(snowball);
            g.transform.position = s;
            return;

        }
    }

    public void FixedUpdate()
    {

        // 跳躍           
        RaycastHit2D hit1 = Physics2D.Linecast(topCheck.position, this.transform.position, 1 << LayerMask.NameToLayer("ground"));
        RaycastHit2D hit2 = Physics2D.Linecast(downCheck.position, this.transform.position, 1 << LayerMask.NameToLayer("ground"));
        RaycastHit2D hit = Physics2D.Linecast(frontCheck.position, this.transform.position);
        h = Random.Range(0, 100);
        Rigidbody2D rb = this.transform.gameObject.GetComponent<Rigidbody2D>();

        Debug.DrawLine(this.transform.position, topCheck.position);
        Debug.DrawLine(this.transform.position, downCheck.position);
        Debug.DrawLine(this.transform.position, frontCheck.position);

        if (hit && hit.transform.gameObject.tag == "wall" || hit.transform.gameObject.tag == "destroyer")
        {
            Vector3 s = this.transform.localScale;//
            s.x = -s.x;
            this.transform.localScale = s;
        }
        else if (hit2 && hit && hit.transform.gameObject.tag == "ground")
        {
            monsterJump = true;
        }
        else
        {    //隨機方向         
            if (h == 2)
            {
                Vector3 s = this.transform.localScale;
                s.x = -s.x;
                this.transform.localScale = s;
            }
        }
        //移動     
        Vector2 x = new Vector2(-this.transform.localScale.x * MonsterMoveForce, rb.velocity.y);
        rb.velocity = x;
        this.gameObject.GetComponent<Animator>().SetTrigger("move");
        //跳躍
        if (hit1 && hit2 && h == 3)
        {
            monsterJump = true;
        }
        if (monsterJump)
        {
            rb.AddForce(Vector2.up * monsterJumpForce);
            monsterJump = false;
        }
    }
    public void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "ground")
        {
            this.gameObject.GetComponent<Animator>().SetTrigger("ground");
        }
        if (collision.gameObject.tag == "bullet")
        {
            hp--;
        }
    }
    public void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "ground")
        {
            this.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 0);
            this.gameObject.GetComponent<Animator>().SetTrigger("groundl");
        }
    }

}

創建雪球:

1. 創建snowball對象給其一張默認的圖片精靈,給snowball對象添加Rigidbody2D和lColider2D組件使其可以進行物理運動和碰撞行,並把它做成預制體。

9kZKde.png
9kZmqO.png
9kZuZD.png

2.給snowball對象添加腳本通過編輯代碼,添加狀態機使雪球狀態可以切換。

public class Snowball : MonoBehaviour
{


    StateMachine<Snowball> stateMachine = new StateMachine<Snowball>();

    public Sprite snowball1;
    public Sprite snowball2;
    public Sprite snowball3;

    public GameObject monster;
    public Transform frontCheck;

    public GameObject[] props;

    public GameObject balldestory;

    // Use this for initialization
    //雪球狀態
    public class SnowballStateB : State<Snowball>
    {
        public float explodeTime = 0;
        public bool gun = false;
        public float gunForce = 3f;

        float dir;

        public override void Enter(Snowball e)
        {
            e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball1; //獲的圖片
            e.gameObject.GetComponent<Animator>().SetTrigger("snowball1");
            e.frontCheck = e.transform.Find("frontCheck");
            e.gameObject.layer = LayerMask.NameToLayer("snowball");
        }
        public override void Update(Snowball e)
        {

            //雪球沒滾時隔 6 個時間點恢復成版雪球
            if (gun == false)
            {
                explodeTime += Time.deltaTime;
                if (explodeTime > 6)
                {
                    explodeTime = 0;
                    e.stateMachine.ChangeState(new SnowballStateA());
                    return;
                }
            }
            else if (gun)
            {
                Rigidbody2D rb = e.gameObject.GetComponent<Rigidbody2D>();
                rb.freezeRotation = false;

                Vector2 v = new Vector2(dir * gunForce, rb.velocity.y);
                // rb.AddForce(v);
                rb.velocity = v;

                Collider2D[] enemies = Physics2D.OverlapCircleAll(e.transform.position, 0.05f, 1 << LayerMask.NameToLayer("monster"));

                foreach (Collider2D a in enemies)
                {
                    Vector2 s = a.gameObject.transform.position;
                    Destroy(a.gameObject);
                    GameObject prop = Instantiate(e.props[Random.Range(0, e.props.Length)]);
                    prop.transform.position = s;
                }
            }
        }
        public override void OnCollisionStay2D(Snowball e, Collision2D collision)
        {

            ContactPoint2D[] a = collision.contacts;
            if (gun == false)
            {
                if (collision.gameObject.tag == "player" && collision.gameObject.transform.FindChild("Gun").GetComponent<Gun>().isFire)
                {
                    //  dir = -GameObject.Find("hero").transform.localScale.x;
                    gun = true;
                    dir = -collision.transform.localScale.x;
                }
            }
        }
        public override void OnCollisionEnter2D(Snowball e, Collision2D collision)
        {

            if (gun == false)
            {
                if (collision.gameObject.tag == "snowball")
                {
                    gun = true;
                    dir = -collision.transform.localScale.x;
                }
            }

            if (gun)
            {
                if (collision.gameObject.tag == "wall" || collision.gameObject.tag == "snowball")
                {
                    dir = -dir;
                }
                if (collision.gameObject.tag == "player")
                {
                    //TODO
                    //雪球帶着主角走
                    //transform.SetParent//設置父節點 
                    //collision.transform.SetParent(e.transform);
                    //collision.transform.position = e.transform.position;
                    //torque //旋轉
                }
            }
            if (collision.gameObject.tag == "destroyer")
            {
                e.gameObject.GetComponent<Animator>().SetTrigger("destrayer");
            }
        }
        public override void Exit(Snowball e)
        {

        }

    }
    //半雪球狀態
    public class SnowballStateA : State<Snowball>
    {
        public float explodeTime = 0;
        int hp = 0;
        public override void Enter(Snowball e)
        {
            e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball2;
            e.gameObject.GetComponent<Animator>().SetTrigger("snowball2");
            e.gameObject.layer = LayerMask.NameToLayer("monster");
            hp = 2;
        }
        public override void Update(Snowball e)
        {
            print(hp);
            if (hp <= 0)
            {
                e.stateMachine.ChangeState(new SnowballStateB());
                return;
            }
            explodeTime += Time.deltaTime;
            if (explodeTime > 5 && hp > 0)
            {
                explodeTime = 0;
                e.stateMachine.ChangeState(new SnowballState());
                return;
            }
        }
        public override void Exit(Snowball e)
        {

        }
        public override void OnCollisionEnter2D(Snowball e, Collision2D collision)
        {

            if (collision.gameObject.tag == "bullet")
            {
                hp--;
            }
        }
    }
    //monster被攻擊狀態;
    public class SnowballState : State<Snowball>
    {
        public float explodeTime = 0;
        Vector3 s;
        public int hp = 0;
        public override void Enter(Snowball e)
        {
            //取得圖片精靈

            e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball3;
            e.gameObject.GetComponent<Animator>().SetTrigger("snowball3");
            e.gameObject.layer = LayerMask.NameToLayer("monster");
            hp = 3;
        }
        public override void Update(Snowball e)
        {
            print(hp);
            if (hp <= 0)
            {
                e.stateMachine.ChangeState(new SnowballStateA());
                hp = 0;
                return;
            }

            explodeTime += Time.deltaTime;
            print(explodeTime);
            //經過多少時    
            if (explodeTime > 4 && hp > 0)
            {
                explodeTime = 0;
                hp = 0;
                s = e.gameObject.transform.position;
                GameObject g = Instantiate(e.monster);
                g.transform.position = s;
                Destroy(e.gameObject);
                return;
            }

        }
        public override void OnCollisionEnter2D(Snowball e, Collision2D collision)
        {
            if (collision.gameObject.tag == "bullet")
            {
                hp--;
            }

        }
    }

    void Start()
    {
        stateMachine.Init(this, new SnowballState());
    }
    // Update is called once per frame
    void Update()
    {

    }
    public void FixedUpdate()
    {
        stateMachine.Update();
    }

    public void OnCollisionEnter2D(Collision2D collision)
    {
        stateMachine.OnCollisionEnter2D(this, collision);
    }

    public void OnCollisionStay2D(Collision2D collision)
    {
        stateMachine.OnCollisionStay2D(this, collision);
    }
    public void Destory()
    {
        Instantiate(balldestory);
        Destroy(this.gameObject);
    }


}

創建道具

1.添加道具預制體.
2.雪球撞到敵人時敵人死亡,在敵人死亡的地方隨機生成一種道具。
3.主角吃到道具增加屬性或者加分。

過關判定

  1. 判斷場景中沒有敵人並且沒有雪球並且沒有道具就過關了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM