[入門教程]Blender+Unity全流程做一個完整的游戲

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制角色行為,包括基礎(chǔ)旋轉(zhuǎn),移動,狀態(tài)機動畫播放,跳躍,和開火
/// </summary>
public class PlayerController : MonoBehaviour
{
??//基礎(chǔ)移動變量定義
??public float walkSpeed = 2;
??public float runSpeed = 6;
??//跳躍行為變量定義
??public float gravity = -12;
??public float jumpHeight = 1;
??float velocityY;
??//獲取其他組件
??public GameObject LaserPrefab;
??public Transform firePosition;
??private Animator animator;
??private CharacterController characterController;
??Transform cameraT;
??void Start()
??{
????//初始化組件
????characterController = GetComponent<CharacterController>();
????animator = GetComponentInChildren<Animator>();
????cameraT = Camera.main.transform;
??}
??// Update is called once per frame
??
??void FixedUpdate()
??{
????//讀取虛擬軸,構(gòu)建虛擬二維方向向量
????Vector2 input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
????Vector2 inputDir = input.normalized;
????//當(dāng)輸入不為零時,根據(jù)方向向量旋轉(zhuǎn)角色
????if (inputDir != Vector2.zero)
????{
??????//通過三角函數(shù)把輸入轉(zhuǎn)為旋轉(zhuǎn)角度,弧度轉(zhuǎn)角度,在y方向上旋轉(zhuǎn),并加上鼠標(biāo)轉(zhuǎn)動的角度
??????transform.eulerAngles = Vector3.up * (Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg + cameraT.eulerAngles.y);
????}
????bool running = Input.GetKey(KeyCode.LeftShift);
????//檢測跑步狀態(tài),給速度加上向量乘數(shù)
????float speed = ((running ? runSpeed : walkSpeed)) * inputDir.magnitude;
????//模擬重力影響,給角色加上一個向下的速度
????velocityY += Time.fixedDeltaTime * gravity;
????//合并向前的速度和向下受重力影響的速度
????Vector3 velocity = transform.forward * speed + Vector3.up * velocityY;
????//按合并速度移動角色
????characterController.Move(velocity * Time.fixedDeltaTime);
????//檢測角色是否觸地,如果觸地,把垂直方向上的速度清零
????if (characterController.isGrounded)
????{
??????velocityY = 0;
????}
????//跳躍函數(shù)
????if (Input.GetKey(KeyCode.Space))
????{
??????Jump();
????}
????//開火函數(shù)
????if (Input.GetMouseButton(0))
????{
??????Fire();
????}
????//控制動畫播放
????float animationSpeedPercent = ((running) ? 1 : .5f) * inputDir.magnitude;
????animator.SetFloat("SpeedPercent", animationSpeedPercent);
??}
??//根據(jù)重力公式,給角色一個向上的速度模擬跳躍
??void Jump()
??{
????//判斷角色是否觸地
????if (characterController.isGrounded)
????{
??????//重力公式,v^2=2gh
??????float jumpVelocity = Mathf.Sqrt(-2 * gravity * jumpHeight);
??????velocityY = jumpVelocity;
????}
??}
??//在頭部位置生成激光
??void Fire()
??{
????Instantiate(LaserPrefab, firePosition.position, firePosition.rotation);
??}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制第三人稱攝像機
/// </summary>
public class ThirdPersonCamera : MonoBehaviour
{
??//定義公共變量
??public float mouseSensitivity = 10;
??public Transform target;
??public float offset;
??public Vector2 pitchMinMax = new Vector2(-40, 85);
??public bool lockCursor;
??//定義偏航控制攝像機水平移動,俯仰角控制攝像機上下移動
??float yaw = 0;
??float pitch = 0;
??private void Start()
??{
????//隱藏鼠標(biāo)
????if (lockCursor)
????{
??????Cursor.lockState = CursorLockMode.Locked;
??????Cursor.visible = false;
????}
??}
??void Update()
??{
????//把鼠標(biāo)橫向移動傳給偏航,縱向移動傳給俯仰角
????yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
????pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
????//限制俯仰角最大最小范圍
????pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
????//構(gòu)建模擬向量控制攝像機旋轉(zhuǎn)
????Vector3 targeteRotation = new Vector3(pitch, yaw);
????//旋轉(zhuǎn)攝像機
????transform.eulerAngles = targeteRotation;
????//控制攝像機向后偏移目標(biāo)
????transform.position = target.position - transform.forward * offset;
??}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Rendering;
using UnityEngine;
/// <summary>
/// 控制敵人行為,自動索敵,遇襲后播放爆炸動畫
/// </summary>
public class EnemyBehaviour : MonoBehaviour
{
??//定義外部變量
??public float enemySpeed = 5f;
??public float deathDistance = 0.8f;
??public float respondDistance = 200;
??public GameObject explosionPrefab;
??//獲取玩家目標(biāo)
??GameObject player;
??float distance;
??void Start()
??{
????player = GameObject.FindGameObjectWithTag("Player");
??}
??void Update()
??{
????//計算敵人和玩家距離
????distance = Vector3.Distance(player.transform.position, transform.position);
????//如果距離小于索敵距離,敵人轉(zhuǎn)向玩家,并朝玩家移動
????if (distance < respondDistance)
????{
??????transform.LookAt(player.transform);
??????transform.Translate(Vector3.forward * enemySpeed * Time.deltaTime);
????}
????//如果與玩家距離過小,游戲結(jié)束
????if (distance < deathDistance)
????{
??????Time.timeScale = 0;
????}
??}
??//被激光集中后,生成爆炸預(yù)制件,總敵人數(shù)減一,玩家得分加一
??private void OnTriggerEnter(Collider other)
??{
????//判斷擊中物體標(biāo)簽是否為激光
????if (other.tag == "Laser")
????{
??????//播放爆炸動畫
??????Instantiate(explosionPrefab, transform.position + new Vector3(0, 1, 0), transform.rotation);
??????//摧毀敵人
??????Destroy(gameObject);
??????//敵人數(shù)減一
??????EnemyGenerator.enemyCount--;
??????//玩家得分加一
??????EnemyGenerator.point++;
????}
??}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 定義激光行為
/// </summary>
public class LaserBehaviour : MonoBehaviour
{
??//定義外部變量激光飛行速度
??public float laserSpeed = 50f;
??void Start()
??{
????//激光生成后10秒銷毀
????Destroy(gameObject, 10f);
????//獲取子集中的剛體組件,與敵人進行碰撞檢測
????GetComponentInChildren<Rigidbody>().velocity = transform.forward * laserSpeed;
??}
??private void OnTriggerEnter(Collider other)
??{
????//擊中物體后摧毀激光
????Destroy(gameObject);
??}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制爆炸動畫
/// </summary>
public class ExplosionBehaviour : MonoBehaviour
{
??void Start()
??{
????//生成后1秒即銷毀
????Destroy(gameObject,1f);
??}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 在地圖上隨機生成敵人,記錄敵人總數(shù),玩家得分,游戲結(jié)束后用退格鍵退出游戲
/// </summary>
public class EnemyGenerator : MonoBehaviour
{
??//定義外部變量
??public GameObject enemyPrefab;
??public float enemyRange = 100f;
??public int totalEnemy = 100;
??public float CD = 1f;
??private float timer = 0;
??public static int enemyCount = 0;
??public static int point = 0;
??void Update()
??{
????//計時器開始計時
????timer += Time.deltaTime;
????//當(dāng)計時器時間超過CD時間而且地圖上的敵人數(shù)小于最高敵人數(shù)
????if (timer > CD && enemyCount <= totalEnemy)
????{
??????//計時器清零
??????timer = 0;
??????//重置CD
??????CD = Random.Range(0.3f, CD);
??????//計算隨機位置
??????Vector3 pos = transform.position + Vector3.forward * Random.Range(-enemyRange, enemyRange) + Vector3.right * Random.Range(-enemyRange, enemyRange);
??????//在隨機位置生成敵人
??????Instantiate(enemyPrefab, pos, transform.rotation);
??????//總敵人數(shù)加一
??????enemyCount++;
????}
????//按空格鍵退出游戲
????if (Input.GetKey(KeyCode.Backspace))
????{
??????Application.Quit();
????}
??}
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
//控制UI,在UI上實時更新敵人數(shù)和玩家得分
public class TextPoints : MonoBehaviour
{
??TMP_Text textMesh;
??void Start()
??{
????//獲取TextMeshPro組件
????textMesh = GetComponent<TMP_Text>();
??}
??void Update()
??{
????//打印敵人數(shù)和玩家得分
????textMesh.text = "Total Enemy: " + EnemyGenerator.enemyCount + " Points: " + EnemyGenerator.point;
??}
}