U3D 2D游戏之黑暗纪元 2D游戏基础入门开发全(1)
第一个U3D 2D游戏的例子,全部自己编写,算是入门用,这里记录一下。
1.首先游戏把层次布置好,这里分为 背景层,游戏层,UI层
背景层 (Background-1):就是单纯的背景显示作用。
游戏层 (Background-2): 主角和障碍物。
UI层 (Canvas):存放UI相关的东西。
背景层 :这里可以随便布置一些背景,就算不布置也无所谓,我这里就随便找了几个图布置了一下。
不过这里需要注意的就是背景层和游戏层的层次关系一定要分好,因为后面的射线需要去区分。
游戏层:游戏层的主要就是障碍物和主角,障碍物分很多,不一定就是单纯的阻碍寻找的,这里指的障碍物是所以能够碰撞产生效果的。
先讲解主角:主角要添加一个Animator,用来控制主角的动画状态。
然后给主角添加一些组件。
主角的运动脚本:
NarutoMove.cs
using UnityEngine; using System.Collections; public class NarutoMove : MonoBehaviour { private float moveSpeed; private bool grounded = false; public Transform Line_floor; private bool jump = false; //角色的跳起 private float jumpy = 200f; private Animator Nurutoanimator; public AudioClip JumpMusic;//跳跃音频 private AudioSource audio; // Use this for initialization void Start () { Nurutoanimator = this.GetComponent<Animator>(); audio = Camera.main.GetComponent<AudioSource>(); } // Update is called once per frame void Update () { float inputx = Input.GetAxis("Horizontal"); //获得水平移动 float inputy = Input.GetAxis("Vertical"); //获得垂直移动 if ((Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)) && (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S))) { //为反反向 if (inputx <0) { this.transform.rotation = Quaternion.Euler(0, -180, 0); moveSpeed = -2f; }else { this.transform.rotation = Quaternion.Euler(0, 0, 0); moveSpeed = 2f; } // this.transform.Translate(new Vector3(1, 0, 0)* moveSpeed * Time.deltaTime); this.transform.Translate(inputx * moveSpeed * Time.deltaTime, inputy * moveSpeed * Time.deltaTime, 0); //this.transform.Rotate(new Vector3(inputx * 180, 0, 0)); Nurutoanimator.SetBool("RunFlg", true); } else { Nurutoanimator.SetBool("RunFlg", false); } Debug.DrawLine(transform.position, Line_floor.transform.position, Color.red, 1f); //与地面接触为真,才能够进行跳跃 grounded = Physics2D.Linecast(transform.position, Line_floor.transform.position, 1 << LayerMask.NameToLayer("Ground")); if (grounded && Input.GetKeyDown(KeyCode.J)) { jump = true; //设置角色的起跳功能 if (jump == true) { Musiplay(audio,JumpMusic); Nurutoanimator.SetBool("RunJumpFlg", true); // AudioSource.PlayClipAtPoint(jumpclips, gameObject.transform.position); 角色跳跃音效 gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(1f, jumpy)); //添加一个向上Y的力 //hero.AddForce(new Vector2(0f,1000f)); jump = false; grounded = false; } } else { Nurutoanimator.SetBool("RunJumpFlg", false); } } //播放跳跃音乐 void Musiplay(AudioSource audio, AudioClip clip) { audio.volume = 1f; audio.PlayOneShot(clip); audio.volume = 0.2f; } }
Health.cs主角的血量控制脚本
using UnityEngine; using System.Collections; using UnityEngine.UI; public class Health : MonoBehaviour { public int Hp; private Slider slider; private Text time; private int HpCnt = 30; // Use this for initialization public float fireRate = 3f;//冷却时间 private float nextFire = 0.0f; void Start () { //this.GetComponent<text slider = GameObject.FindGameObjectWithTag("Hp").GetComponent<Slider>(); time = GameObject.FindGameObjectWithTag("Time").GetComponent<Text>(); } // Update is called once per frame void Update () { time.text = Time.time.ToString(); CutHp(); } //每隔一定的时间2s会减少2滴血 public void CutHp() { //冷却时间 //最开始Time.time ==0 nextFire==3 所以3S过后,Time.time > nextFire if (Time.time > nextFire) { nextFire = Time.time + fireRate; Hp = Hp - 2; slider.value = Hp; if (Hp <= 0) { Application.LoadLevel("GameOver"); Destroy(this.gameObject); } } } public void AddHP(int damageCount,int HPCount) { Hp += damageCount; if(Hp >= HPCount){ Hp = HPCount; } slider.value = Hp; if (Hp <=0) { Destroy(this.gameObject); } } void OnCollisionEnter2D(Collision2D collision) { AddHealth foodHealth = collision.collider.gameObject.GetComponent<AddHealth>(); if (foodHealth != null) { AddHP(foodHealth.AddTime, HpCnt); Destroy(foodHealth.gameObject); } } }
游戏层中的障碍物:
障碍物也就具有个重力和碰撞器属性,用来阻止主角通过。
游戏层中的水果:
用来给主角加血液,创建一个空物体。然后添加一个脚本,给里面指定一些预置体。
FoodColltor.cs
using UnityEngine; using System.Collections; public class FoodColltor : MonoBehaviour { public GameObject[] Foods; private int FoodType; private float fireRate = 5.0f;//冷却时间 private float nextFire = 0.0f;//定位时间基准 private Transform Playertransform; private float deathTime = 6.0f; // Use this for initialization void Start () { //得到玩家的坐标 Playertransform = GameObject.FindGameObjectWithTag("Player").transform; } // Update is called once per frame void Update () { //在一定的时间生成水果,和在一定的时间删除水果 FoodTimeColltor(); } //每隔一定的时间,3个水果 void FoodTimeColltor() { if (Time.time > nextFire) { nextFire = Time.time + fireRate; RandomCreateFood(3); } } //随机生成水果 public void RandomCreateFood(int FoodNum) { for (int i = 0; i < FoodNum; i++) { FoodType = Random.Range(0, Foods.Length); Vector2 foodPosition = new Vector2(Playertransform.position.x + Random.Range(0, 5), transform.position.y + Random.Range(0,0.8f)); GameObject food = GameObject.Instantiate(Foods[FoodType], foodPosition, Quaternion.Euler(new Vector3(0, 0, 0))) as GameObject; food.transform.parent = this.transform; //设定水果的父游戏对象 this.FooddDeath(food); } } //水果的死亡,到一定的时间后对自动死亡 public void FooddDeath(GameObject food) { Destroy(food, deathTime); } }
最后给相机加一个跟随主角运动脚本。
CameraMove.cs
using UnityEngine; using System.Collections; public class CameraMove : MonoBehaviour { private Transform Playertransform; // Use this for initialization void Start () { //获得游戏玩家对象 Playertransform = GameObject.FindGameObjectWithTag("Player").transform; } // Update is called once per frame void LateUpdate () { //将游戏对象的坐标赋给相机的坐标 //transform.position = new Vector3(Playertransform.position.x, -1.0f, -3.5f); 会稍微出现卡顿的现象 // transform.position = Playertransform.position transform.position = new Vector2(Playertransform.position.x+2f, -0.1f); } }
游戏:http://pan.baidu.com/s/1hsIxUug
源码: