遊戲性編程是指經過一系列遊戲系統將遊戲想法變成現實的過程。編程
本次的簡例以NPC設計爲主。編輯器
一般在進行腳本設計前,對NPC的屬性進行基本的添加和設定,諸如動畫系統、物理系統等等。ide
1.動畫系統動畫
添加Animator組件,綁定骨骼。this
建立Animator Controller文件,將之添加到組件的Controller部分。spa
打開Controller,考慮動畫組件的主體須要實現什麼功能。設計
以此例的NPC爲例,須要實現他的移動功能。3d
因此在Controller中添加新的混合樹命名爲Locomotion(移動)。code
打開混合樹,爲其添加三種不一樣的運動狀態(空閒、走路、奔跑),並綁定相應的動畫文件。orm
調整三個狀態之間的數值階段,初始爲0:0.5:1,調整爲0:1:8。
(這裏的意義在於更流暢的移動體驗,休閒到走路快速的過渡,走路到奔跑則須要速度到達必定閾值後才能切換。)
備註:
取消勾選Autonate Thresholds後,能夠更改數值。
parameter是用於腳本中調用setFloat方法中的參數名,從而在動畫間不斷的切換。
【2】Player腳本
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMovement : MonoBehaviour { public float moveSpeed; private Vector3 moveInput; private Vector3 moveVelocity; private Rigidbody rd; private Camera mainCamera; private Animator animator; // Start is called before the first frame update
void Start() { rd = GetComponent<Rigidbody>(); mainCamera = Camera.main; animator = GetComponent<Animator>(); } // Update is called once per frame
void Update() { float lh = Input.GetAxis("Horizontal");//輸入的是左右,即X軸數據,對應着AD鍵位。
float lv = Input.GetAxis("Vertical");//輸入的是上下,即Z軸的數據,對應着WS鍵位。
moveInput =new Vector3(lh,0f,lv); //一個即時的向量,當無輸入時是零向量。 //在Unity中,人物面朝的方向是藍軸,即Z軸;沿着人物雙手方向的橫軸是紅軸,即X軸;||而沿着人物垂心的是綠軸,即Y軸。
Vector3 cameraForword = mainCamera.transform.forward; //主相機在沿着z軸的矢量位置和方向
cameraForword.y = 0; Quaternion s = Quaternion.FromToRotation(Vector3.forward, cameraForword); //這個四元素包含了(0,0,1)到cameraForword的旋轉信息
Vector3 lookToward = s * moveInput; //四元數和向量相乘表示這個向量按照這個四元數進行旋轉以後獲得的新的向量。
if (moveInput.sqrMagnitude>0) { Ray ray = new Ray(transform.position,lookToward); //transform.position爲該腳本對應的對象的位置
transform.LookAt(ray.GetPoint(1)); //transform.LookAt:旋轉自身,使得當前對象的正z軸指向目標對象target所在的位置(使對象朝向目標點) //ray.GetPoint(1):獲取一個沿着向量方向距離X的點
} moveVelocity = transform.forward*moveSpeed* moveInput.sqrMagnitude; //transform.forward給的是人物座標軸Z軸的矢量方向,即面朝的方向 //(自動對物體旋轉值算出前進方向向量的變量,vector3.forward則不計算旋轉值,因此vector3.forward固定爲(0,0,1)) //moveVector3.sqrMagnitude返回是座標軸輸入矢量的平方長度的Float數值,用於控制速度,當無輸入時,速度爲0。
Aniamting(); } void FixedUpdate() { rd.velocity = moveVelocity; } void Aniamting() { animator.SetFloat("Blend",rd.velocity.magnitude); //調用animator.SetFloat方法,能夠設置混合樹中的參數數值,參數名字以自定義的參數名爲準
} }
【3】scriptableobject(Unity中用於處理序列化的結構)
一個容許你存儲大量獨立於腳本實例的共享數據的類。
目的是經過避免對值進行復制而減小內存的開銷。
定義了一個繼承自ScriptableObject的類,你能夠使用CreateAssetMenu attribute用你的類建立自定義assets。
下面爲實例:
Player加載的類
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharacterStats : MonoBehaviour { //Stats:一個統計玩家數據的類
#region MyRegion
//#region 是 C# 預處理器指令。 #region 是一個分塊預處理命令,它主要是用於編輯器代碼的分塊,在編譯時會被自動刪除。 //#region 在使用 Visual Studio 代碼編輯器的大綱顯示功能時指定可展開或摺疊的代碼塊。有助於代碼的整潔。 // public static CharacterStats instance; void Awake() { instance = this;//傳遞自身的地址 } #endregion
public int MaxHealth = 100; public int CurrentHealth { get; private set; } //能夠公共獲取,但只能在該類中設置。
void Start() { CurrentHealth = MaxHealth; } public void takeDamage(int damage) { CurrentHealth -= damage; if (CurrentHealth <= 0) { Dead(); } } public void TreatHealth(int treat) { print("treat:"+treat); CurrentHealth += treat; print(CurrentHealth); if (CurrentHealth >= 100) { print("你恢復了健康"); } } public void Dead() { print("You Dead"); } }
互動對象體加載的類:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ItemPickUp : Interacrable { //繼承自Interacrable類(含有與環境互動的代碼)
public Itemss item; CharacterStats charStatss=new CharacterStats(); public override void Interact()//重寫了父類的方法,並搭載的本身的內容
{base.Interact(); PickUp(); } void PickUp() { item.Use();//這裏使用的派生類的基類,但實際上傳遞的是根據Item基類自定義的assets。
Destroy(gameObject); } }
如下是相關的類,並未直接加載到對象上:
using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = " NewItems",menuName = "Inventory/Item")] public class Itemss : ScriptableObject {//建立assets的基類
new public string name = "Item"; public Sprite icon = null; public virtual void Use() { } }
using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "New Health Potion",menuName = "Inventory/Item/Health Potion")] public class HealthPotion : Itemss { //繼承自Item類的子類,是assets新的藍本。
public int HealthModifity; private CharacterStats charStats; void Start() { charStats=CharacterStats.instance; } public override void Use() { base.Use(); ApplyEffect(); } void ApplyEffect() { CharacterStats.instance.TreatHealth(HealthModifity);//傳遞了玩家參數類的方法。
} }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Interacrable : MonoBehaviour { //包含玩家與環境互動的類
public bool interacting = false; private Renderer rend; public Material[] materials; void Start() { rend = GetComponent<Renderer>(); rend.enabled=true;//啓用渲染器,使渲染的對象可見
rend.sharedMaterial = materials[0]; //Renderer.sharedMaterial:修改模型材質的顏色,或者是修改材質Shader的一些屬性。 //(此方法使用的材料是共享的材料,內存中只有一份,不建議對材料作修改)
} void Update() { if (interacting&&Input.GetKeyDown(KeyCode.Alpha1)) {Interact(); } if (interacting) { rend.sharedMaterial = materials[1]; } else { rend.sharedMaterial = materials[0]; } } public virtual void Interact() {//虛方法,子類可加Override進行重寫,虛方法自己有方法體。
Destroy(gameObject); } void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "Player") { interacting = true; } } void OnTriggerExit(Collider other) { if (other.gameObject.tag == "Player") { interacting = false; } } }