Unity编程-初级篇

发布于:2022-11-09 ⋅ 阅读:(545) ⋅ 点赞:(0)

一.Awake和Start

using UnityEngine;
using System.Collections;

public class AwakeAndStart : MonoBehaviour
{
    void Awake ()
    {
        Debug.Log("Awake called.");
    }
    
    
    void Start ()
    {
        Debug.Log("Start called.");
    }
}

在对象本身激活的情况下,如果脚本处于未激活状态,进入游戏时,依然会调用Awake,输出“Awake called.”语句。

在对象本身激活的情况下,只有在脚本激活的状态下,进入游戏时,才会调用Start,输出"Start called."语句。

若对象未激活,两者都不会调用。

二.矢量数学

Vector3.Magnitude用于计算向量长度

Vector3.Cross(Vector A,Vector B);用于计算两个向量的叉积,此方法可以用于寻找垂直于向量A,B的向量C,从而确定转轴。

三.启用和禁用组件

主要通过:组件.enabled = false(true)来禁用(启用)组件,在此之前要先通过GetComponent获取组件。

using UnityEngine;
using System.Collections;

public class EnableComponents : MonoBehaviour
{
    private Light myLight;
    
    
    void Start ()
    {
        myLight = GetComponent<Light>();
    }
    
    
    void Update ()
    {
        if(Input.GetKeyUp(KeyCode.Space))
        {
        	//此句代码可以实现类似开关功能
			//将组件设为非当前值
            myLight.enabled = !myLight.enabled;
        }
    }
}

四.激活游戏对象

using UnityEngine;
using System.Collections;

public class ActiveObjects : MonoBehaviour
{
    void Start ()
    {
        gameObject.SetActive(false);
    }
}

五.Transform 和Rotate

using UnityEngine;
using System.Collections;

public class TransformFunctions : MonoBehaviour
{
    public float moveSpeed = 10f;
    public float turnSpeed = 50f;
    
    
    void Update ()
    {
    	//改变物体的z轴,使其向前移动
        if(Input.GetKey(KeyCode.UpArrow))
            transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
        //改变物体的z轴,使其向后移动
        if(Input.GetKey(KeyCode.DownArrow))
            transform.Translate(-Vector3.forward * moveSpeed * Time.deltaTime);
        //改变物体的x轴,使其向左转动
        if(Input.GetKey(KeyCode.LeftArrow))
            transform.Rotate(Vector3.up, -turnSpeed * Time.deltaTime);
        //改变物体的x轴,使其向右转动
        if(Input.GetKey(KeyCode.RightArrow))
            transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
    }
}

注:

Vector3.up=(0,1,0);

Vector3.forward=(0,0,1);

 Vector3.right=(1,0,0);//这三个值始终不变,可以理解为常量

六.Look At

此方法可以使相机跟随目标物体移动

using UnityEngine;
using System.Collections;

public class CameraLookAt : MonoBehaviour
{
    public Transform target;
    
    void Update ()
    {
        transform.LookAt(target);
    }
}

七.线性插值

// 在此示例中,result = 4
float result = Mathf.Lerp (3f, 5f, 0.5f);

在制作游戏时,可能需要在两个值之间进行线性插值,这时可以通过Lerp函数来完成。线性插值会在给定的两个值之间找到某个百分比的值。

Math.Lerp函数接收三个float参数:Mathf.Lerp (float1,float2,float3);

float1表示要进行插值的起始值,float2表示插值的结束值。

float3表示要进行插值的距离,如果为0,则返回float1的值,如果为1,则返回float2的值。

在某些情况下,可使用Lerp函数使值随时间平滑:

经过几帧过后,光强度将会趋近于8,但随着接近目标,其变化速率将减慢

void Update ()
{
    light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f);
}

如果不希望光强每帧改变,而是按秒改变,则可使用以下代码:

void Update ()
{
    light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f * Time.deltaTime);
}

八.Destroy

Destroy函数可以用来摧毁物体本身,也可以用来摧毁物体上的组件:

using UnityEngine;
using System.Collections;

public class DestroyBasic : MonoBehaviour
{
    void Update ()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            Destroy(gameObject);
        }
    }
}
using UnityEngine;
using System.Collections;

public class DestroyOther : MonoBehaviour
{
    public GameObject other;
    
    
    void Update ()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            Destroy(other);
        }
    }
}
using UnityEngine;
using System.Collections;

public class DestroyComponent : MonoBehaviour
{
    void Update ()
    {
        if(Input.GetKey(KeyCode.Space))
        {
            Destroy(GetComponent<MeshRenderer>());
        }
    }
}

九.GetButton和GetKey

GetKey方法需要使用KeyCode.固定键位进行操作,而GetButton方法可以通过Input Manager自定义操作键位及键位引用名称,所以更推荐使用GetButton。

以下着重介绍GetButton方法:

GetButtonDown:只有按下Button的第一帧返回true,其他时间都返回false。

GetButton:只要Button处于按下的状态,就一直返回true,直至松开按钮。

GetButtonUp:只有松开Button的第一帧返回true,其他时间都返回false。

GetKey的情况与GetButton相同。

十.GetAxis

GetAxis("Horizontal");//对应键盘上的A键和D键 或←键和→键

GetAxis("Vertical"); //对应键盘上的W键和S键 或↑键和↓键

GetAxis("Mouse X"); //对应X方向上鼠标的移动

GetAxis("Mouse Y"); //对应Y方向上鼠标的移动

十一.OnMouseDown

检测碰撞体或GUI元素上的鼠标点击

using UnityEngine;
using System.Collections;

public class MouseClick : MonoBehaviour
{
    void OnMouseDown ()
    {
        rigidbody.AddForce(-transform.forward * 500f);
        rigidbody.useGravity = true;
    }
}

十二.DeltaTime

游戏中每一帧所花费的时间可能不同,当帧率改变时,游戏中物体的移动会变得忽快忽慢,此时可以将原来的移动数值用Time.DeltaTime修正,,这样即使帧率变化,物体速度也会保持恒定。

using UnityEngine;
using System.Collections;

public class UsingDeltaTime : MonoBehaviour
{
    public float speed = 8f; 

    void Update ()
    {
         if(Input.GetKey(KeyCode.RightArrow))
            transform.position += new Vector3(speed * Time.deltaTime, 0.0f, 0.0f);
    }   
}

十三.数据类型

(1)数值类型(Value)

包括:int, float, double, bool, char, Structs(Vector3, Quaternion).

(2)引用类型(Reference)

包括:Classes(Transform, GameObject).

using UnityEngine;
using System.Collections;

public class DatatypeScript : MonoBehaviour 
{
    void Start () 
    {
        //值类型变量,transform.position不会改变
        Vector3 pos = transform.position;
        pos = new Vector3(0, 2, 0);
        
        //引用类型变量,transform会改变
        Transform tran = transform;
        tran.position = new Vector3(0, 2, 0);
    }
}

十四.类

脚本的名称与类名是一致的,若要更改脚本名称,则类名也需一起更改。

使用类将不同功能的代码模块区分开,提高代码的可读性

using UnityEngine;
using System.Collections;

public class SingleCharacterScript : MonoBehaviour
{
    public class Stuff
    {
        public int bullets;
        public int grenades;
        public int rockets;
        //构造函数
        public Stuff(int bul, int gre, int roc)
        {
            bullets = bul;
            grenades = gre;
            rockets = roc;
        }
    }
    
    
    public Stuff myStuff = new Stuff(10, 7, 25);
    public float speed;
    public float turnSpeed;
    public Rigidbody bulletPrefab;
    public Transform firePosition;
    public float bulletSpeed;
    
    
    void Update ()
    {
        Movement();
        Shoot();
    }
    
    
    void Movement ()
    {
        float forwardMovement = Input.GetAxis("Vertical") * speed * Time.deltaTime;
        float turnMovement = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
        
        transform.Translate(Vector3.forward * forwardMovement);
        transform.Rotate(Vector3.up * turnMovement);
    }
    
    
    void Shoot ()
    {
        if(Input.GetButtonDown("Fire1") && myStuff.bullets > 0)
        {
            Rigidbody bulletInstance = Instantiate(bulletPrefab, firePosition.position, firePosition.rotation) as Rigidbody;
            bulletInstance.AddForce(firePosition.forward * bulletSpeed);
            myStuff.bullets--;
        }
    }
}

using UnityEngine;
using System.Collections;

public class Inventory : MonoBehaviour
{
    public class Stuff
    {
        public int bullets;
        public int grenades;
        public int rockets;
        public float fuel;
        
        public Stuff(int bul, int gre, int roc)
        {
            bullets = bul;
            grenades = gre;
            rockets = roc;
        }
        
        public Stuff(int bul, float fu)
        {
            bullets = bul;
            fuel = fu;
        }
        
        // 构造函数
        public Stuff ()
        {
            bullets = 1;
            grenades = 1;
            rockets = 1;
        }
    }
    

    // 创建 Stuff 类的实例(对象)
    public Stuff myStuff = new Stuff(50, 5, 5);
    
    public Stuff myOtherStuff = new Stuff(50, 1.5f);
    
    void Start()
    {
        Debug.Log(myStuff.bullets); 
    }
}

十五.Instantiate

using UnityEngine;
using System.Collections;

public class UsingInstantiate : MonoBehaviour
{
    public Rigidbody rocketPrefab;
    public Transform barrelEnd;
    
    
    void Update ()
    {
        if(Input.GetButtonDown("Fire1"))
        {
            Rigidbody rocketInstance;
        	//克隆预制体后,将类型强行转换为Rigidbody,以便实现后续操作。
            rocketInstance = Instantiate(rocketPrefab, barrelEnd.position, barrelEnd.rotation) as Rigidbody;
            rocketInstance.AddForce(barrelEnd.forward * 5000);
        }
    }
}

使用Instantiate来创建预制体的克隆体,但是产生的克隆体并不会消失,需要一个额外的脚本来处理产生后的克隆体,在一定的时间内,销毁克隆体。

using UnityEngine;
using System.Collections;

public class RocketDestruction : MonoBehaviour
{
    void Start()
    {
        Destroy (gameObject, 1.5f);
    }
}

十六·.Invoke

使用Invoke函数在规定的时间过后调用指定函数

using UnityEngine;
using System.Collections;

public class InvokeScript : MonoBehaviour 
{
    public GameObject target;
    
    
    void Start()
    {
        Invoke ("SpawnObject", 2);
    }
    
    void SpawnObject()
    {
        Instantiate(target, new Vector3(0, 2, 0), Quaternion.identity);
    }
}

使用InvokeRepeating函数,规定函数调用的时间间隔

using UnityEngine;
using System.Collections;

public class InvokeRepeating : MonoBehaviour 
{
    public GameObject target;
    
    
    void Start()
    {
        InvokeRepeating("SpawnObject", 2, 1);
    }
    
    void SpawnObject()
    {
        float x = Random.Range(-2.0f, 2.0f);
        float z = Random.Range(-2.0f, 2.0f);
        Instantiate(target, new Vector3(x, 2, z), Quaternion.identity);
    }
}

若要暂停InvokeRepeating方法,可以使用CancelInvoke("函数名")。

本文含有隐藏内容,请 开通VIP 后查看