Notas de estudio de Angry Birds de U2D

# 官方文档:https://docs.unity3d.com/ScriptReference/index.html

Parte 1

基本操作
1.左下角Project面板中Assets下创建Image,Music,Scenes,Script四个文件夹,Packages不用管
2.在Scenes文件夹下新建几个unity场景文件,把预先备好的素材拉入Image与Music
3.选中Image下第一张图,例如BIRDS_1,右边Inspector面板中设置Sprite Mode为Multiple,点sprite Editor,在新窗口中点Slice并保存
4.回来Image文件夹下会看到BIRDS_1可以再细分许多子图并且已经自动命名
5.其他图片一样操作,至此素材导入完成
6.点击对应的Scene,把所需图片拉到左上方Hierarchy面板下,每个Scene都会自带一个Main Camera
7.在中间上方的Scene面板中摆放图片与摄像机的位置,操作方法跟小学时学的3DMAX差不多
8.点击正上方运行按钮,在正下方的Game面板中观察摄像机的映像,当然此时未设置动画
9.最后就是不断给场景中的对象在右边Inspector面板中add component,完

Parte 2

Inspector面板
1、可见,对象ID(对应代码),静态,Tag,Layer(新建一个层把用到的素材全部拉进去)
2、Transform是本对象的资态:世界XYZ绝对坐标,俯仰角/偏航角/翻滚角,XYZ缩放比例
3、Sprite Renderer:Sprite设置素材源,Order in Layer可以设置在本Layer中的等级,值越大越靠前显示
4、其他的Component就需要点击最下面的Add Component添加,添加脚本是直接输入脚本名确认,建议是脚本名与对象名能够对应
5、以下面的代码为例,有四个响应事件的API,还有三个局部变量,凡是设成public的变量可以在Inspector面板中直接更改他的值
//Bird.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Brid : MonoBehaviour{
    private bool isClick=false;
    public Transform rightPos;
    public float maxDis=3;
    private void OnMouseDown(){//对本对象鼠标按下左键时的事件
        isClick=true;
    }
    private void OnMouseUp(){//对本对象鼠标释放左键时的事件
        isClick=false;
    }
    private void Update(){//本对象每帧显示前的事件
        if(isClick){
            transform.position=Camera.main.ScreenToWorldPoint(Input.mousePosition);//重点!
            transform.position+=new Vector3(0,0,-Camera.main.transform.position.z);
            if(Vector3.Distance(transform.position,rightPos.position)>maxDis){
                Vector3 pos=(transform.position-rightPos.position).normalized;//方向不变长度变成1
                pos*=maxDis;//让向量乘上最大距离得到相对于基点的向量
                transform.position=pos+rightPos.position;//偏移向量+基点向量
            }
        }
    }
    private void Start(){//本对象第一帧显示前的事件
        //可以设置初始姿态什么的
    }
}
//这里要对上面的“重点”解释一下:
//屏幕按下对象有Input.mousePosition,然后转换成世界坐标得到transform.position,transform就是本对象
//2D场景平行视角摄像机默认坐标是(0,0,-10),摄像头面向Z轴正向,坐标转换后的坐标是落在摄像头所在摄影平面的!
//摄像机对用户触摸屏幕点坐标的转换时XY坐标可以正确转换,但是Z坐标会变成取摄像机的坐标,所以z坐标要减去摄像机z坐标

Parte 3

Rigidbody 2D:当Boty Type为Dynamic时绑定动力学(如自由落体等)引擎,例如小鸟,angular drag是滚动摩擦系数
Rigidbody 2D:当Boty Type为Kinematic时绑定不受动力学引擎,例如用户拖动小鸟时
(当然用户拖动时用Dynamic也OK,反正脚本中重设了对象坐标,但是这样释放时飞出去的速度会很大)
Rigidbody 2D:当Boty Type为Static时绑定可以作为Spring Joint 2D的Connected Rigid Body参数的值(弹簧另一端),例如树枝
Spring Joint 2D:绑定弹簧关节引擎,Connected Rigit Body参数是弹簧的另一端,Frequnecy是阻尼系数
Circle Collider 2D:绑定圆形碰撞引擎,Radius参数是响应半径
Box Collider 2D:绑定矩形碰撞引擎,Edit Collider可以设置响应边框

Parte 4 El pájaro vuela

private SpringJoint2D sp;
private Rigidbody2D rg;
private void Awake(){
    sp=GetComponent<SpringJoint2D>();
    rg=GetComponent<Rigidbody2D>();
}
private void OnMouseDown(){
    isClick=true;
    rg.isKinematic=true;//不受动力学控制,可以让用户自由拖动
}
private void OnMouseUp(){
    isClick=false;
    rg.isKinematic=false;//受动力学控制,计算受力改变其速度
    Invoke("Fly",0.1f);//计算受重力与弹簧力0.1秒之后执行Fly函数
}
private void Fly(){
    sp.enabled=false;//弹簧失效,注意Frequency的值是阻尼系数
}

Escena de la parte 5

对THEME_01_THEME_1中进行slice得到地面拉到场景中
Add Componenet-Box Collider 2D-Edit Collider把碰撞框上边线往下拉一点让鸟在草上滚
新建env文件夹把THEME_01_THEME_1_0放进去,ctrl+d复制多份并在Scene面板中往右拉铺满整个场景
然后再把小草与天空放上来即可

Parte 6 Cerdo

//BIRDS_1_103拉进去场景并更改ID为pig
//添加Circle Collider 2D,按Edit Collider调整大小
//添加Rigidbody 2D,调整 Angular Drag为2
//添加Add Component,添加下面代码
public class Pig : MonoBehaviour{
    public float maxSpeed=5.0f;
    public float minSpeed=3.0f;
    private SpriteRenderer render;//精灵渲染类对象声明
    public Sprite hurt;
    private void Awake(){
        render=GetComponent<SpriteRenderer>();//定义对象为绑定的本对象
    }
    private void OnCollisionEnter2D(Collision2D collision){//碰撞检测
        print(collision.relativeVelocity.magnitude);
        if(collision.relativeVelocity.magnitude<minSpeed){
            return ;
        }
        else if(collision.relativeVelocity.magnitude>maxSpeed){
            Destroy(gameObject);
        }else if(collision.relativeVelocity.magnitude<maxSpeed && collision.relativeVelocity.magnitude>minSpeed){
            render.sprite=hurt;
        }
    }
}
//回到Inspector面板中调整上面三个public参数,hurt的值是BIRDS_1_104图片

parte 7 tirachinas

//左树枝left_branch加Line Renderer并设材质,在其下创建空对象并更名为leftPos
//右树枝right_branch加Line Renderer并设材质,在其下创建空对象并更名为rightPos(前面画弹簧建了可跳过)
//在Bird类中加入四个public成员,并在Inspector面板中拖动赋值
public LineRenderer right;//这四变量是树枝对象的子类对象,要在Inspector面板中赋值
public LineRenderer left;
public Transform leftPos;
public Transform rightPos;
//在update函数处加入四行代码
right.SetPosition(0,rightPos.position);
right.SetPosition(1,transform.position);
left.SetPosition(0,leftPos.position);
left.SetPosition(1,transform.position);

parte 8 efectos de la muerte

拖死亡动画第一帧到场景,重命名为Boom
增加Boom.cs脚本
public class Boom : MonoBehaviour{
    public void destroying(){
        Destroy(gameObject);
    }
}
增加Animator,ctrl+6打开动画编缉器,按create创建一个动画,放到Assets下的Animation下(无就新建)
依次拖入关键帧,并在最后一帧添加事件destroying,把场景中的Boom拖动到Assets下的prefabs下(无就新建)
在Pig.cs中,猪destroy函数后加上Instantiate(boom,transform.position,Quaternion.identity);
类成员中加上public GameObject boom;,回到Inspector面板把prefabs下的Boom拉到脚本赋值处

parte 9 puntuación efectos especiales

拖分数到场景重命名为pigScore,再拖动到prefabs下,在Pig.cs中,在上面给死亡动画Instantiate下再写:
GameObject go=Instantiate(score,transform.position+new Vector3(0,0.8f,0),Quaternion.identity);
Destroy(go,1.5f);
在声明类成员变量时写public GameObject score;,回到Inspector面板把prefabs下的pigScore拉到脚本赋值处

parte 10 gestión del juego (puntos pesados ​​y difíciles)

//创建新的空类GameManager,往GameManager.cs中写入
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour{
    public List<Bird> birds;
    public List<Pig> pigs;
    public static GameManager _instance;
    private void Awake(){
        _instance=this;
    }
    private void Start(){
        Initialized();
    }
    private void Initialized(){
        for(int i=0;i<birds.Count;i++){
            if(i==0){
                birds[i].enabled=true;
                birds[i].sp.enabled=true;
                //birds[i].cc.enabled=true;
            }else{
                birds[i].enabled=false;
                birds[i].sp.enabled=false;
                //birds[i].cc.enabled=false;
            }
        }
    }
    public void NextBird(){
        if(pigs.Count>0){
            if(birds.Count>0){
                Initialized();
            }else{
                print("lose"); 
            }
        }else{
            print("win");
        }
    }
}
//往inspector面板中按顺便拖入鸟与猪
//Bird.cs中设置在Fly()后触发Next()唤醒下一只鸟
private void Fly(){
    sp.enabled=false;//弹簧失效,注意Frequency的值是阻尼系数
    Invoke("Next",5);
}
private void Next(){
    GameManager._instance.birds.Remove(this);
    Destroy(gameObject);
    Instantiate(boom,transform.position,Quaternion.identity);
    GameManager._instance.NextBird();
}
//至此游戏主体实现完成!!!

parte 11 en el árbol

GameManager.cs的Awake中加上originPos=birds[0].transform.position;
GameManager.cs的Initialized中加上birds[0].transform.position=originPos;
Bird.cs的OnMouseUp末加上right.enabled=false;left.enabled=false;

parte 12 tirachinas

Bird.cs的Update中SetPosition前加上right.enabled=true;left.enabled=true;

parte 13 bloque de madera

1. 插入多种木块图
2. 创建Rigidbody 2D使用物理学引擎如自由落体
3. 创建Box Collider 2D使用盒式碰撞引擎
4. 使用pid脚本并赋hurt/score/ispid参数
5. copy多份

parte 14 interfaz de ganar-perder

在Hierarchy界面下创建UI-Image重命名为lose,是全屏黑,不透明度一半
在lose下创建UI-Image重命名为menu,是左1/3屏黑,不透明度0
在menu创建UI-Image重命名为retry,插图是重玩按扭图片
在menu创建UI-Image重命名为exit,插图是退出按扭图片
(千万不要拉到prefabs下!)
在Hierarchy界面下创建UI-Image重命名为win,是全屏黑,不透明度一半
在lose下创建UI-Image重命名为menu,是左1/3屏黑,不透明度0
在menu创建UI-Image重命名为next,插图是下一关按扭图片
在menu创建UI-Image重命名为exit,插图是退出按扭图片
(千万不要拉到prefabs下!)
修改GameManager.cs
声明变量public GameObject Win;并把lose拉过来属性面板赋值
声明变量public GameObject Loss;并把lose拉过来属性面板赋值
在输出失败后加上Loss.SetActive(true);
在输出成功后加上Win.SetActive(true);
(补充说明下layer与sorting layer:)
sorting layer用于渲染,Unity渲染关系层级顺序:Camera -> sorting layer -> sorting order
layer用于碰撞检测,光线投射

parte 15 evento de botón (reproducir / siguiente nivel / salir)

File-Build Setting-把全部unity场景文件拉上去
在GameManager.cs中写三个函数
public void Next(){SceneManager.LoadScene(3);}
public void Replay(){SceneManager.LoadScene(2);}
public void Home(){SceneManager.LoadScene(1);}
给三个按钮Add Component-OnClick,把GameManager拉过来,再选对应的函数

parte 16 seguimiento de la cámara

改摄像机的x坐标,涉及的接口:
static function Lerp (from : Vector3, to : Vector3, t : float) : Vector3 
---->返回值=from+(to-from)*t
Mathf.Clamp(float value,float min,float max)
---->在 Mathf.Clamp 中传入三个参数:value,min,max,限制 value的值在min,max之间,如果value大于max,则返回max,如果value小于min,则返回min,否者返回value;
Time.deltaTime
---->每帧间隔时间,如20帧每秒,即0.05秒/帧,则Time.deltaTime=0.05
写法一:Camera.main.transform.position=new Vector3(Mathf.Clamp(posX,0,15),Camera.main.transform.position.y,Camera.main.transform.position.z);
缺点:跟随可以实现,但是换鸟是会突然转变
写法二:float posX=transform.position.x;
Camera.main.transform.position=Vector3.Lerp(Camera.main.transform.position,\
                                            new Vector3(Mathf.Clamp(posX,0,15),\
                                                        Camera.main.transform.position.y,\
                                                        Camera.main.transform.position.z),\
                                            3*Time.deltaTime);
这个函数的意义:相机初始坐标0,0,-10,小鸟坐标的x在大于0时,返回值=from+(to-from)*t!=from产生跟随,且t是3*Time.deltaTime小于1所以不是即时跟随,平滑换鸟
3这个值的意义是1秒移动3米,太小的话相机跟不上,太大的话换鸟时会突然变化镜头位置,要自己调参得出

parte 17 cargando musica

public AudioClip birdCollision;
if(collision.gameObject.tag=="Player")AudioSource.PlayClipAtPoint(birdCollision,transform.position);

parte 18 pájaro amarillo

//换贴图
//写脚本Bird_yellow.cs继承
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bird_yellow : Bird{
    private bool fly_again;
    private new void Awake(){
        base.Awake();
        fly_again=false;
    }
    private new void OnMouseDown(){
        if(isFlying){
            if(!fly_again){
                rg.velocity*=2;
                fly_again=true;
            }
            return ;
        }
        if(!isClick)AudioSource.PlayClipAtPoint(select,transform.position);
        isClick=true;
        rg.isKinematic=true;
    }
}
//在面板重新赋值,GameManager也要赋
//测试参数

parte 19 pájaro verde

//换贴图
//写脚本Bird_green.cs继承
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bird_green : Bird{
    private bool fly_again;
    private new void Awake(){
        base.Awake();
        fly_again=false;
    }
    private new void OnMouseDown(){
        if(isFlying){
            if(!fly_again){
                Vector3 speed=rg.velocity;
                speed.x*=-1;
                rg.velocity=speed;
                fly_again=true;
            }
            return ;
        }
        if(!isClick)AudioSource.PlayClipAtPoint(select,transform.position);
        isClick=true;
        rg.isKinematic=true;
    }
}

//在面板重新赋值,GameManager也要赋
//测试参数

parte 20 menú de inicio

Escena de apertura: inserte la imagen de fondo, inserte el botón UI (ingrese el botón del juego y salga del botón del juego), vincule los dos métodos escritos a continuación,
cree el objeto GameManager y escriba GameManager.cs

public class StartMenuManager : MonoBehaviour{
    public void Enter(){
        //print("enter");
        UnityEngine.SceneManagement.SceneManager.LoadScene(1);
    }
    public void Exit(){
        //print("exit");
        #if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
        #else
            Application.Quit();
        #endif
    }
}

menú del nivel de la parte 21

Escena de nivel: inserte la imagen de fondo, la imagen del botón de nivel 1, la imagen del botón de nivel 2, la imagen del botón de nivel 2, la imagen del botón de retroceso.
Recuerde agregar el método Collider (Box o Circle está bien) y escriba una clase para responder a OnMouseDown ()
con LevelPageSalir como ejemplo:

public class LevelPageExit : MonoBehaviour{
    public void OnMouseDown(){
        UnityEngine.SceneManagement.SceneManager.LoadScene(0);
    }
}

Organizar notas

  1. Los atributos Panel Inspector
    Transformar la postura de la escena de cada objeto es
    Sprite Renderer Los objetos del mapa son
    Circle Collider Detección de colisión circular 2D
    Box Collider Detección de colisión 2D rectangular
    Rigidbody Motor de cuerpo rígido 2D
    (estático es estacionario, el otro extremo del resorte, por ejemplo, ramas de árbol)
    (dinámico tiene análisis de fuerza, como masa, coeficiente de fricción deslizante, coeficiente de fricción rodante, aceleración gravitacional, etc., pero no incluye colisión Collider)
    (Kinematic no tiene análisis de fuerza y ​​solo se puede operar por transformación, como el arrastre del dedo del usuario )
    Motor de resorte Spring Joint 2D
    (si el otro extremo del resorte es el atributo Rigidbody)
    Script escrito por el script
    Line Renderer renderizado lineal

  2. Obtener las coordenadas de los demás y de usted mismo
    Coordenadas propias: transform.position, de hecho, omite esta, o sí mismo,
    las coordenadas de otros: public List birds ;;
    private Vector3 originPos;
    originPos = birds [0] .transform.position;

  3. Cambiar el motor de otros objetos
    en Bird.cs
    [HideInInspector]
    public SpringJoint2D sp;
    private void Awake () {sp = GetComponent ();}
    en GameManager.cs
    public List birds;
    birds [i] .enabled = true; // El El script Bird.cs del i bird entra en vigor
    birds [i] .sp.enabled = true; // La propiedad SpringJoint2D del i bird entra en vigor
    birds [i] .enabled = false; // Bird.cs del i bird El script no es válido
    birds [i] .sp.enabled = false; // El atributo SpringJoint2D del i-ésimo pájaro no es válido

  4. Cambie su propio motor de física (consulte bird.cs)
    private Rigidbody2D rg; // default Dynamic
    private void Awake () {rg = GetComponent ();}
    rg.isKinematic = true; // No está controlado por dinámica, lo que permite a los usuarios para arrastrar libremente Dynamic
    rg.isKinematic = false; // Bajo el control de la dinámica, calcular la fuerza para cambiar su velocidad

  5. Detección de colisiones y toma de velocidad relativa (consulte pig.cs)
    private void OnCollisionEnter2D (Collision2D collision) {print (collision.relativeVelocity.magnitude);}

  6. Cambie su propia textura (consulte pig.cs)
    public Sprite hurt; // hurt manualmente pase en
    privado SpriteRenderer render en el panel ;
    private void Awake () {render = GetComponent ();}
    render.sprite = hurt;
    si lo desea para cambiarlo externamente Para texturas, consulte el punto 3

  7. Producción de animación (consulte boom.cs)
    arrastre un fotograma a la escena
    ctrl + 6 para crear una animación en la carpeta Animación
    escriba un guión
    para este objeto para agregar eventos desencadenantes al fotograma clave, como autodestrucción, destrucción de
    vacío público ( ) {Destroy (gameObject);}
    Arrastra el objeto a la carpeta Prefabs, el objeto de la escena está configurado como no válido

  8. Crear y destruir otros objetos (consulte pig.cs)
    public GameObject boom; // boom pasar manualmente en
    Instantiate (boom, transform.position, Quaternion.identity) en el panel ; // Generar la
    puntuación explosiva pública de GameObject en su lugar; / / Score pasar manualmente en
    GameObject en el panel go = Instantiate (score, transform.position + new Vector3 (0,0.8f, 0), Quaternion.identity); //
    Destroy (go, 1.5f); // 1.5 segundos Post -destrucción

  9. Salto de botón (consulte GameManager.cs)
    Cree una imagen de interfaz de usuario en la escena,
    vincule el evento Button,
    vincule el objeto GameManager,
    vincule el evento correspondiente public void Replay () {SceneManager.LoadScene (ID de escena);}

  10. 音乐 播放
    público AudioClip birdCollision;
    if (collision.gameObject.tag == “Player”) AudioSource.PlayClipAtPoint (birdCollision, transform.position);


  11. Encapsulación orientada a objetos :
    se puede acceder al público a voluntad, se puede heredar mediante objetos de subclase, incluidos los parámetros pasados ​​en el panel Inspector
    protegido se puede acceder por uno mismo, se puede heredar mediante objetos de subclase, no se mostrarán en el panel Inspector
    privado se puede acceder por uno mismo, no por subclases La herencia de objetos no se mostrará en el panel Inspector.
    Herencia:
    pájaro rojo básico, derivado del pájaro amarillo y pájaro verde (habilidades adicionales)
    polimorfismo:
    el GameManager en cada escena necesita usar List para mantener todas las aves, incluidas las aves rojas, las aves amarillas, las aves verdes, puede declarar que el elemento de la lista es la clase base Bird

  12. Haga clic en el evento
    Método 1: extraiga la imagen, agregue propiedades de colisión (¡debe!), Personalice una clase para implementar el método OnMouseDown ()
    Método 2: cree una imagen de interfaz de usuario, asigne texturas, agregue propiedades de botón, ingrese al objeto del administrador de escenas (vinculando cada El método del botón se ha implementado en la clase), seleccione el método correspondiente


Recuerde cambiar la ruta de la caché en Edit-Preference-GI Cache

Supongo que te gusta

Origin blog.csdn.net/cj1064789374/article/details/114626769
Recomendado
Clasificación