目录
前言
设计要求:
开始前的准备:
准备好预制件“UFO”,具体做法是在场景新建3D模型圆柱体,调整其三维比例后拖拽至项目Assets内。
一、游戏设计
1.资产目录MVC结构:
/Controller
/ActionManager // 动作和动作管理器模块
KActionManager.cs // 动力学运动管理器
PActionManager.cs // 物理运动管理器
KinematicFlyAction.cs // 动力学运动实现
PhysisAction.cs // 物理运动实现
/ActionPack //动作接口、模版、抽象类
IActionManager.cs // 动作管理器接口
ISSActionCallback.cs // 回调接口
SSAction.cs // 抽象动作
SSActionManager.cs // 动作管理器模板
/GameControl //游戏控制
ISceneController.cs
Singleton.cs
SSDirector.cs
RoundController.cs
ScoreRecorder.cs
/Model
/Disk //飞碟模型
DiskData.cs // 飞碟基本数据
DiskFactory.cs // 工厂模式产生飞碟
/View //交互模型
IUserAction.cs
UserGUI.cs
2.类的UML设计图
3.难度设置
根据回合数动态调整速度和其他属性
4.分数记录功能分离解释
将分数记录器 (ScoreRecorder
) 从主控制器 (RoundController
) 中分离出来是一个设计上的重要决策,主要是为了增强代码的可维护性、可扩展性和关注点分离。
主控制器 RoundController
负责游戏的整体逻辑,如回合控制、生成飞碟等。如果它同时管理分数计算,将导致它承担过多的职责,代码复杂且难以维护。将分数记录的功能提取到一个独立的类 ScoreRecorder
中,使得每个类只专注于其核心职责,提高了代码的模块化和可读性。
当需要调整或者改变分数逻辑时,只需调整 ScoreRecorder
,RoundController
仍然保持不变。这种解耦使得系统更加灵活。
5.部分技术解释
1.对象池技术。
对象池技术是一种用于管理和复用对象的编程技术,特别适用于那些生命周期短、创建和销毁频繁的对象(如子弹、飞碟等游戏元素)。对象池通过事先创建一组对象并存储在“池”中,当需要时从池中获取对象而不是重新创建,使用后再将对象归还到池中。
飞碟工厂使用对象池技术管理飞碟对象,通过以下步骤提高性能:对象池初始化,创建飞碟,回收飞碟。
最后达到性能优化的目的:对象池避免频繁创建和销毁对象,减少内存开销和性能消耗,特别适用于频繁使用的对象(如飞碟)。
2.刚体(Rigidbody)
在 Unity 中,刚体(Rigidbody) 是一个物理组件,用于让游戏对象受物理引擎的控制。添加刚体组件后,对象会受到重力、碰撞和物理力的影响,能够模拟真实的物理运动效果。刚体通常用于需要动态运动的对象,如角色、车辆、抛射物等。
它的核心属性是Is Kinematic:如果设置为 true
,刚体不受物理引擎控制,主要用于需要手动控制位置和旋转的对象。
设置属性:
gameobject.GetComponent<Rigidbody>().isKinematic = true;
二、具体代码
1.)Models
1.DiskData.cs
DiskData
是一个用于表示飞碟数据的类。它包含了飞碟的主要属性,如大小、水平速度、垂直速度、颜色、位置、飞行方向和分数。这个类提供了一个构造函数,可以在创建飞碟对象时初始化这些属性。此外,UpdateSpeed
方法可以用于更新飞碟的水平和垂直速度。
using UnityEngine;
namespace Model.Disk
{
public class DiskData : MonoBehaviour
{
public float Size { get; set; } // 飞碟的大小
public float HorizontalSpeed { get; set; } // 水平速度
public float VerticalSpeed { get; set; } // 垂直速度
public Color Color { get; set; } // 飞碟的颜色
public Vector3 Position { get; set; } // 飞碟的初始位置
public Vector3 Direction { get; set; } // 飞碟的运动方向
public int Score { get; set; } // 飞碟的分数
// 构造函数
public DiskData(float size, float horizontalSpeed, float verticalSpeed, Color color, Vector3 position, Vector3 direction, int score)
{
Size = size;
HorizontalSpeed = horizontalSpeed;
VerticalSpeed = verticalSpeed;
Color = color;
Position = position;
Direction = direction;
Score = score;
}
// 可以通过这个方法更新飞碟的速度
public void UpdateSpeed(float horizontalSpeed, float verticalSpeed)
{
HorizontalSpeed = horizontalSpeed;
VerticalSpeed = verticalSpeed;
}
}
}
2.DiskFactory.cs
DiskFactory
是一个管理飞碟对象的类。它创建飞碟并设置属性,包括大小、速度、颜色和初始位置。CreateDisk 方法用于获取并初始化一个飞碟实例,而 RecycleDisk
方法用于回收飞碟,使其可以被重复使用。
using UnityEngine;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using Unity.VisualScripting.FullSerializer;
namespace Model.Disk
{
public class DiskFactory : MonoBehaviour
{
public GameObject ufoPrefab;
private Queue<GameObject> availableUFOs;
private List<GameObject> activeUFOs;
private void Start()
{
availableUFOs = new Queue<GameObject>();
activeUFOs = new List<GameObject>();
}
public GameObject CreateDisk(int round)
{
GameObject ufo = GetOrCreateUFO(); // 获取或创建一个 UFO
InitializeUFO(ufo, round); // 初始化 UFO 的属性
activeUFOs.Add(ufo); // 添加到活跃 UFO 列表
return ufo;
}
/// <summary>
/// 从可用队列中获取 UFO,如果没有则创建新的 UFO。
/// </summary>
private GameObject GetOrCreateUFO()
{
if (availableUFOs.Count > 0)
{
var ufo = availableUFOs.Dequeue();
ufo.SetActive(true);
return ufo;
}
// 创建新 UFO
GameObject newUFO = Instantiate(Resources.Load("Prefabs/UFO", typeof(GameObject))) as GameObject;
newUFO.AddComponent<DiskData>();
newUFO.AddComponent<Rigidbody>();
return newUFO;
}
/// <summary>
/// 初始化 UFO 的属性。
/// </summary>
/// <param name="ufo">需要初始化的 UFO</param>
/// <param name="round">当前的回合数</param>
private void InitializeUFO(GameObject ufo, int round)
{
var ufoData = ufo.GetComponent<DiskData>();
SetDiskData(ufoData, round); // 设置 UFO 的数据
// 设置外观和位置
ufo.transform.localScale = new Vector3(1f, 0.05f, 1f);
ufo.GetComponent<Renderer>().material.color = ufoData.Color;
ufo.transform.position = ufoData.Position;
// 设置随机旋转角度
var randomRotation = new System.Random();
ufo.transform.localEulerAngles = new Vector3(-randomRotation.Next(-40, 40), 0, 0);
// 设置物理组件和速度
Rigidbody rigidbody = ufo.GetComponent<Rigidbody>() ?? ufo.AddComponent<Rigidbody>();
Vector3 movementVelocity = new Vector3(ufoData.HorizontalSpeed, ufoData.VerticalSpeed, 0);
rigidbody.velocity = movementVelocity;
}
private void SetDiskData(DiskData diskData, int round)
{
diskData.Size = Random.Range(0.5f * round, 2.0f * round);
diskData.HorizontalSpeed = Random.Range(5f, 25f * round);
diskData.VerticalSpeed = Random.Range(0f, 25f * round);
diskData.Score = round * 10;
diskData.Color = Random.ColorHSV();
diskData.Position = new Vector3(-10f, Camera.main.pixelHeight * 0f + 1f, 0); // 左侧偏移
diskData.Direction = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized;
}
public void RecycleDisk(GameObject ufo)
{
ufo.SetActive(false);
ufo.transform.position = Vector3.zero;
ufo.transform.localScale = new Vector3(1f, 0.05f, 1f);
activeUFOs.Remove(ufo);
availableUFOs.Enqueue(ufo);
}
}
}
2.)Controllers/ActionPack
1.SSAction.cs
SSAction
类是动作基类,用于定义游戏对象的行为。它继承自 ScriptableObject
,支持多种行为扩展,包含 Start()
和 Update()
方法,允许在子类中定义自定义的行为逻辑。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SSAction : ScriptableObject
{
public bool enable = true;
public bool destroy = false;
public GameObject gameobject { get; set; }
public Transform transform { get; set; }
public ISSActionCallback callback { get; set; }
protected SSAction() { }
public virtual void Start()
{
throw new System.NotImplementedException();
}
public virtual void Update()
{
throw new System.NotImplementedException();
}
}
2.ISSActionCallback.cs
ISSActionCallback
是一个回调接口,用于在动作完成或状态变化时通知外部。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum SSActionEventType:int { Started, Completed }
public interface ISSActionCallback
{
void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Completed,
int intParam = 0 ,
string strParam = null,
Object objectParam = null);
}
3.SSActionManager.cs
SSActionManager
类用于管理和执行游戏中的动作。它负责添加、更新和删除动作,确保动作按顺序执行。通过该管理器,可以控制不同游戏对象的行为(如飞碟的运动)并在需要时销毁不再使用的动作。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SSActionManager : MonoBehaviour {
public Dictionary <int, SSAction> actions = new Dictionary <int, SSAction> ();
public List <SSAction> waitingAdd = new List<SSAction> ();
public List<int> waitingDelete = new List<int> ();
// Update is called once per frame
public virtual void Moving(GameObject disk) { }
protected void Update () {
foreach (SSAction ac in waitingAdd) actions [ac.GetInstanceID ()] = ac;
waitingAdd.Clear ();
foreach (KeyValuePair <int, SSAction> kv in actions) {
SSAction ac = kv.Value;
if (ac.destroy) {
waitingDelete.Add(ac.GetInstanceID()); // release action
} else if (ac.enable) {
ac.Update (); // update action
}
}
foreach (int key in waitingDelete) {
SSAction ac = actions[key];
actions.Remove(key);
Object.Destroy(ac);
}
waitingDelete.Clear ();
}
public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager) {
action.gameobject = gameobject;
action.transform = gameobject.transform;
action.callback = manager;
waitingAdd.Add (action);
action.Start ();
}
// Use this for initialization
protected void Start () {
}
}
4.IActionManager.cs
IActionManager用于提供简单的接口给控制器调用,以方便控制飞碟行为(主要是飞行和计算其数量并返回)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IActionManager
{
void Flying(GameObject disk);
int UFOCount();
}
3.)Controllers/ActionManager
1.PhysicAction.cs
这个类继承了动作基类,用于控制一个物体(飞碟)在物理世界中的行为,并且具有刚体属性(也就是重力和加速度)。
using UnityEngine;
public class PhysicAction : SSAction
{
public float horizontalSpeed; // 初始水平速度
public static PhysicAction GetAction(float speed)
{
PhysicAction action = ScriptableObject.CreateInstance<PhysicAction>();
action.horizontalSpeed = speed;
return action;
}
public override void Start()
{
Rigidbody rigidbody = gameobject.GetComponent<Rigidbody>();
rigidbody.isKinematic = false;
rigidbody.useGravity = true;
rigidbody.velocity = new Vector3(horizontalSpeed * 5, 0, 0);
}
public override void Update()
{
if (!this.transform.gameObject.activeSelf)
{
this.destroy = true;
this.callback.SSActionEvent(this);
return;
}
// 判断物体是否超出屏幕视口
if (IsOutOfViewport())
{
this.destroy = true;
this.callback?.SSActionEvent(this, SSActionEventType.Completed);
}
}
// 检查物体是否离开屏幕视口
private bool IsOutOfViewport()
{
Vector3 screenPoint = Camera.main.WorldToViewportPoint(this.transform.position);
return screenPoint.x < -0.1f || screenPoint.x > 1.1f || screenPoint.y < -0.1f || screenPoint.y > 1.1f;
}
}
2.PActionManager.cs
物理刚体动作的管理器,PActionManager继承自 SSActionManager
,实现了 ISSActionCallback
和 IActionManager
接口。它主要负责管理与物理相关的动作,如控制飞碟的运动,并在飞碟生命周期结束时回收它。它的方法Start()
在初始化时,从 SSDirector
获取当前场景控制器(RoundController
),并设置为 actionManager
。还实例化了 DiskFactory,
以调用其的回收飞碟的方法。
using Controller.Round;
using Model.Disk;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicActionManager : SSActionManager, ISSActionCallback, IActionManager
{
public RoundController sceneController;
public PhysicAction action;
public DiskFactory factory;
protected new void Start()
{
sceneController = (RoundController)SSDirector.getInstance().currentSceneController;
sceneController.actionManager = this as IActionManager;
factory = Singleton<DiskFactory>.Instance;
}
public void UFOMoving(GameObject disk)
{
float reducedHorizontalSpeed = disk.GetComponent<DiskData>().HorizontalSpeed * 0.06f;
Debug.Log(reducedHorizontalSpeed);
action = PhysicAction.GetAction(reducedHorizontalSpeed);
RunAction(disk, action, this);
}
public int UFOCount()
{
return actions.Count;
}
public void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Completed,
int intParam = 0,
string strParam = null,
Object objectParam = null)
{
factory.RecycleDisk(source.transform.gameObject);
}
protected new void Update() { }
public void UFO() { }
}
3.KinematicFlyAction.cs
运动学飞行的动作类,KinematicFlyAction类继承自SSAction,用于控制飞碟(或其他游戏物体)以运动方向和速度沿平面飞行。它是一个“运动”类,负责在飞碟上应用无重力的物理运动。
using UnityEngine;
public class KinematicFlyAction : SSAction
{
public float horizontalSpeed;
public float verticalSpeed;
private Vector3 direction;
private Camera mainCamera;
public static KinematicFlyAction GetAction(float horizontalSpeed, float verticalSpeed)
{
KinematicFlyAction action = ScriptableObject.CreateInstance<KinematicFlyAction>();
action.horizontalSpeed = horizontalSpeed;
action.verticalSpeed = verticalSpeed;
return action;
}
// 初始化动作
public override void Start()
{
mainCamera = Camera.main;
gameobject.GetComponent<Rigidbody>().isKinematic = true;
this.direction = new Vector3(horizontalSpeed, verticalSpeed, 0);
}
public override void Update()
{
if (this.gameobject == null || !this.gameobject.activeSelf)
{
this.destroy = true;
this.callback?.SSActionEvent(this, SSActionEventType.Completed);
return;
}
// 判断物体是否超出视口
if (IsOutOfViewport())
{
this.destroy = true;
this.callback?.SSActionEvent(this, SSActionEventType.Completed);
return;
}
// 更新物体位置
this.transform.position += this.direction * Time.deltaTime;
}
// 检查物体是否离开屏幕视口
private bool IsOutOfViewport()
{
Vector3 screenPoint = mainCamera.WorldToViewportPoint(this.transform.position);
// 判断物体是否完全超出了屏幕(可以设置适当的缓冲区)
return screenPoint.x < -0.1f || screenPoint.x > 1.1f || screenPoint.y < -0.1f || screenPoint.y > 1.1f;
}
}
4.KActionManager.cs
KActionManager
类继承自 SSActionManager
,实现了 ISSActionCallback
和 IActionManager
接口,负责管理和控制飞碟的动作和生命周期。它与飞碟的运动和回收操作有关。它和PActionManager类似可以控制飞碟的飞行和返回飞碟数量。
using Controller.Round;
using Model.Disk;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KActionManager : SSActionManager, ISSActionCallback, IActionManager
{
public RoundController sceneController;
public KinematicFlyAction action;
public DiskFactory factory;
protected new void Start()
{
sceneController = (RoundController)SSDirector.getInstance().currentSceneController;
sceneController.actionManager = this as IActionManager;
factory = Singleton<DiskFactory>.Instance;
}
public void UFOMoving(GameObject disk)
{
DiskData data = disk.GetComponent<DiskData>();
float reducedHorizontalSpeed = data.HorizontalSpeed * 0.1f;
float reducedVerticalSpeed = data.VerticalSpeed * 0.1f;
Debug.Log(reducedHorizontalSpeed);
Debug.Log(reducedVerticalSpeed);
action = KinematicFlyAction.GetAction(reducedHorizontalSpeed, reducedVerticalSpeed);
RunAction(disk, action, this);
}
public int UFOCount()
{
return actions.Count;
}
public void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Completed,
int intParam = 0,
string strParam = null,
Object objectParam = null)
{
factory.RecycleDisk(source.transform.gameObject);
}
public void UFO() { }
}
4.)Controllers/GameControl
1.SSDirector.cs
SDirector
类是一个 单例模式 的实现,通常用于控制游戏的场景和状态。在 Unity 中,这个类充当了 导演(Director) 的角色,负责管理和协调游戏中的各个部分。在任何地方调用 SSDirector.getInstance()
都会返回同一个实例。这是通过 _instance
私有静态变量实现的,如果实例为空,则创建一个新的 SSDirector
对象。
currentSceneController
是一个 ISceneController
类型的属性,它负责管理当前游戏场景的控制。具体的场景控制器(如 RoundController
)将实现 ISceneController
接口,并通过 SSDirector
来访问。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SSDirector : System.Object {
// singlton instance
private static SSDirector _instance;
public ISceneController currentSceneController { get; set;}
public bool running{ get; set;}
// get instance anytime anywhare!
public static SSDirector getInstance() {
if (_instance == null) {
_instance = new SSDirector ();
}
return _instance;
}
}
2.Singleton.cs
Singleton<T>
类是一个 通用单例模式(Generic Singleton) 的实现,用于确保类 T
在整个应用程序中只有一个实例,并且能够方便地访问这个实例。
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = FindFirstObjectByType<T>();
if (_instance == null)
{
GameObject singletonObject = new GameObject(typeof(T).Name);
_instance = singletonObject.AddComponent<T>();
}
}
return _instance;
}
}
}
3.ISceneController.cs
场景控制器接口,LoadResources()负责导入场景资源,UserAct()提供响应用户交互的接口。
using System;
public interface ISceneController
{
void LoadResources();
void UserAct();
}
4.ScoreRecorder.cs
ScoreRecorder
类是 Unity 游戏中的一个管理类,用于记录和计算玩家的分数。它的主要功能是根据击中的飞碟(hitDisk
)的分数更新总分,并将其显示在用户界面中。
它引用了 RoundController
类,表示当前回合的控制器。ScoreRecorder
会将自己赋值给 roundController.scoreRecorder
,使得回合控制器可以访问到当前的分数记录器。
同时还引用了 UserGUI
类,负责显示用户界面。ScoreRecorder
在 Start()
方法中获取 UserGUI
组件,并在分数更新时与之交互,将当前分数显示在游戏界面中。
using Model.Disk;
using UnityEngine;
namespace Controller.Round
{
public class ScoreRecorder : MonoBehaviour
{
private int score = 0;
public RoundController roundController;
public UserGUI userGUI;
// 计算分数
public void CalculateScore(GameObject hitDisk)
{
score += hitDisk.GetComponent<DiskData>().Score;
userGUI.totalScore = score;
}
void Start()
{
roundController = (RoundController)SSDirector.getInstance().currentSceneController;
roundController.scoreRecorder = this;
userGUI = this.gameObject.GetComponent<UserGUI>();
}
}
}
5.RoundController.cs
RoundController
类负责整个回合的控制流程,管理飞碟的生成、玩家的操作、分数的计算以及游戏结束的判断。它协调了多个组件(如 DiskFactory
、ScoreRecorder
、UserGUI
、PhysicActionManager
、KActionManager
)的工作,确保游戏按照预期的规则进行,并实时更新游戏状态。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using Model.Disk;
using Controller.Round;
public class RoundController : MonoBehaviour, ISceneController, IUserAction
{
GameObject disk;
DiskFactory factory;
public IActionManager actionManager;
public ScoreRecorder scoreRecorder;
public UserGUI userGUI;
int turn = 0;
int mturn = 10;
float timer = 0.5f;
private float spawnTimer = 0.5f; // 每个飞碟的生成间隔
private int disksToSpawn = 0; // 当前回合剩余待生成的飞碟数量
private void Update()
{
if (userGUI.displayMode == 0) return;
UpdateActionManager(); // 确保 ActionManager 的类型正确
UserAct(); // 处理用户输入
gameOver(); // 检查游戏是否结束
if (turn > mturn) return;
UpdateTimers(); // 更新计时器
if (disksToSpawn > 0 && spawnTimer <= 0)
{
SpawnDisks(); // 生成飞碟
}
if (timer <= 0 && actionManager.UFOCount() == 0 && disksToSpawn == 0)
{
StartNewRound(); // 开始新回合
}
}
// 确保 ActionManager 使用正确类型
private void UpdateActionManager()
{
if (!userGUI.useKinematic)
{
actionManager = gameObject.GetComponent<PhysicActionManager>() as IActionManager;
}
else
{
actionManager = gameObject.GetComponent<KActionManager>() as IActionManager;
}
}
// 更新计时器
private void UpdateTimers()
{
timer -= Time.deltaTime;
if (disksToSpawn > 0)
{
spawnTimer -= Time.deltaTime;
}
}
// 生成飞碟
private void SpawnDisks()
{
disk = factory.CreateDisk(turn);
actionManager.UFOMoving(disk);
disksToSpawn--; // 减少待生成飞碟数
spawnTimer = 0.5f; // 重置生成间隔
}
// 开始新回合
private void StartNewRound()
{
disksToSpawn = turn+4; // 当前回合需要生成的飞碟数量
turn++;
if (turn <= mturn)
{
userGUI.currentRound = turn;
}
timer = Mathf.Max(4.0f - turn * 0.5f, 1.0f); // 动态调整每回合等待时间,避免前期等待过久
}
void Awake()
{
InitDirector();
InitComponent();
}
void InitDirector()
{
SSDirector director = SSDirector.getInstance();
director.currentSceneController = this;
}
void InitComponent()
{
gameObject.AddComponent<UserGUI>();
gameObject.AddComponent<PhysicActionManager>();
gameObject.AddComponent<KActionManager>();
gameObject.AddComponent<ScoreRecorder>();
gameObject.AddComponent<DiskFactory>();
factory = Singleton<DiskFactory>.Instance;
userGUI = gameObject.GetComponent<UserGUI>();
}
public void gameOver()
{
if (turn > mturn && actionManager.UFOCount() == 0)
userGUI.feedbackMessage = "Game Over!";
}
public void UserAct()
{
if (Input.GetButtonDown("Fire1"))
{
Camera ca = Camera.main;
Ray ray = ca.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
scoreRecorder.CalculateScore(hit.transform.gameObject);
hit.transform.gameObject.SetActive(false);
}
}
}
void Start() { }
}
5.)Views
1.IUserAction
IUserAction
是一个接口,定义了两个方法:gameOver()
和 UserAct()
,这两个方法是游戏控制和用户交互的核心。
主要功能:gameOver()
:用于处理游戏结束时的逻辑。UserAct()
:用于处理玩家的操作输入,如点击或其他互动。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//用户接口
public interface IUserAction
{
void gameOver();
void UserAct();
}
2.UserGUI.cs
UserGUI
类处理游戏中的图形用户界面(GUI),包括显示玩家的分数、回合信息,并管理游戏的界面切换。它为玩家提供了直观的反馈和交互功能,帮助玩家在游戏中进行操作。
using UnityEngine;
public class UserGUI : MonoBehaviour
{
public int displayMode;
public int totalScore;
public int currentRound;
public string feedbackMessage;
public bool useKinematic;
private IUserAction playerAction;
public GUIStyle headerStyle, defaultStyle, labelStyle;
public Font gameFont; // 引用字体
private int btnWidth, btnHeight;
void Start()
{
btnWidth = Screen.width / 5;
btnHeight = Screen.width / 10;
if (gameFont == null)
{
Debug.LogError("Font not assigned.");
return;
}
headerStyle = CreateGUIStyle(gameFont, 50, Color.white, TextAnchor.MiddleCenter);
labelStyle = CreateGUIStyle(gameFont, 20, Color.white, TextAnchor.MiddleCenter);
defaultStyle = CreateGUIStyle(null, 50, Color.black, TextAnchor.MiddleCenter);
useKinematic = true;
displayMode = 0;
feedbackMessage = "";
playerAction = SSDirector.getInstance().currentSceneController as IUserAction;
}
private GUIStyle CreateGUIStyle(Font font, int fontSize, Color color, TextAnchor alignment)
{
GUIStyle style = new GUIStyle
{
font = font,
fontSize = fontSize,
normal = { textColor = color },
alignment = alignment
};
return style;
}
void OnGUI()
{
GUI.skin.button.fontSize = 20;
GUI.skin.button.font = gameFont; // 设置按钮使用的字体
if (displayMode == 0)
{
ShowMainMenu();
}
else if (displayMode == 1)
{
ShowGameScreen();
}
}
void ShowMainMenu()
{
GUI.Label(new Rect(Screen.width / 2 - btnWidth * 0.5f, Screen.height * 0.1f, btnWidth, btnHeight), "点击开始游戏", headerStyle);
if (GUI.Button(new Rect(Screen.width / 2 - btnWidth * 0.5f, Screen.height * 3 / 7, btnWidth, btnHeight), "开始"))
{
displayMode = 1;
}
}
void ShowGameScreen()
{
GUI.Label(new Rect(300, 60, 50, 200), feedbackMessage, headerStyle);
GUI.Label(new Rect(280, 0, 100, 50), "分数: " + totalScore, labelStyle);
GUI.Label(new Rect(560, 0, 100, 50), "当前回合: " + currentRound, labelStyle);
// 根据 useKinematic 的值动态设置按钮文本
string buttonText = useKinematic ? "切换到物理模式" : "切换到运动学模式";
// 显示按钮并根据当前模式切换
if (GUI.Button(new Rect(0, 0, 200, 50), buttonText))
{
useKinematic = !useKinematic;
}
}
}
总结
以上就是本文的内容,说明如何使用unity制作在物理引擎作用下的打飞碟游戏。
项目地址:天明五蕴/Unity游戏打飞碟