本文章只提供代码,资源请自行到资源商店挑选自己喜欢的模型,音乐,图片(原创作品)
人物
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using TMPro;
public class playerove : MonoBehaviour
{
public static int health = 100; // 初始血量
public float speed;
public float jumpForce = 5f; // 跳跃力大小
public float groundCheckDistance = 0.1f; // 地面检测距离
private Rigidbody rb;
private bool isGrounded; // 是否在地面上
public int jumpcount; // 可实现任意段数跳跃
public Animator animator;
public float mouseSensitivity = 1f;
public float upDownRange = 60f;
private float verticalRotation = 0;
private CharacterController characterController;
private Vector3 birthPosition;
public AudioSource audioSource; // 音频源组件
public AudioClip moveSound; // 移动音效
public AudioClip jumpSound; // 跳跃音效
public AudioClip fallDamageSound; // 摔落受伤音效
public AudioClip respawnSound; // 复活音效
public Slider healthSlider; // 血量滑动轮
public float fallDamageThreshold = 2f; // 摔落造成伤害的最小高度
public float fallDamageMultiplier = 10f; // 摔落高度与伤害的乘数
private float startFallY; // 开始下落的 Y 坐标
private bool isFalling; // 是否正在下落
public TextMeshProUGUI respawnText; // 复活提示文本
[Header("移动设置")]
public float normalSpeed = 5f; // 普通移动速度
public float sprintSpeed = 8f; // 加速移动速度
public float stamina = 100f; // 耐力值
public float staminaDepletionRate = 20f; // 耐力消耗速度
public float staminaRecoveryRate = 15f; // 耐力恢复速度
public Slider staminaSlider; // 耐力条UI
private bool isSprinting = false; // 是否正在冲刺
void Start()
{
rb = GetComponent<Rigidbody>();
characterController = GetComponent<CharacterController>();
// 记录出生位置
birthPosition = transform.position;
audioSource = gameObject.AddComponent<AudioSource>();
audioSource.spatialBlend = 1.0f; // 启用3D音效
audioSource.rolloffMode = AudioRolloffMode.Linear; // 线性衰减
audioSource.minDistance = 5f;
audioSource.maxDistance = 30f;
audioSource.dopplerLevel = 0f; // 禁用多普勒效应
// 初始化血量滑动轮
if (healthSlider != null)
{
healthSlider.maxValue = health;
healthSlider.value = health;
}
// 初始时隐藏复活提示文本
if (respawnText != null)
{
respawnText.enabled = false;
}
speed = normalSpeed;
// 初始化耐力条
if (staminaSlider != null)
{
staminaSlider.maxValue = stamina;
staminaSlider.value = stamina;
}
}
// Update is called once per frame
void Update()
{
// 将不需要每帧执行的代码改为间隔执行
if (Time.frameCount % 3 == 0)
{ // 每3帧执行一次
UpdateHealthCheck();
}
Move();
Jump();
view();
HandleSprinting(); // 处理冲刺逻辑
}
void HandleSprinting()
{
// 检测Shift键按下
bool wantToSprint = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
// 只有在地面移动时才能冲刺
bool canSprint = isGrounded && (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0);
// 耐力系统逻辑
if (wantToSprint && canSprint && stamina > 0)
{
isSprinting = true;
speed = sprintSpeed;
stamina -= staminaDepletionRate * Time.deltaTime;
// 确保耐力不低于0
stamina = Mathf.Max(0, stamina);
}
else
{
isSprinting = false;
speed = normalSpeed;
// 恢复耐力
if (stamina < 100f)
{
stamina += staminaRecoveryRate * Time.deltaTime;
stamina = Mathf.Min(100f, stamina);
}
}
// 更新耐力条UI
if (staminaSlider != null)
{
staminaSlider.value = stamina;
}
}
void UpdateHealthCheck()
{
// 检查是否正在下落
if (rb.velocity.y < 0)
{
if (!isFalling)
{
startFallY = transform.position.y;
isFalling = true;
}
}
else if (isFalling)
{
float fallDistance = startFallY - transform.position.y;
if (fallDistance > fallDamageThreshold)
{
TakeFallDamage(fallDistance);
}
isFalling = false;
}
// 检查血量
if (health <= 0)
{
Respawn();
}
// 更新血量UI
if (healthSlider != null)
{
healthSlider.value = health;
}
}
public void Move()
{
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 target = new Vector3(horizontal * speed * Time.deltaTime, 0, vertical * Time.deltaTime * speed);
target = transform.rotation * target;
transform.position = transform.position + target;
// 更新动画参数
if (animator != null)
{
float moveMagnitude = new Vector2(horizontal, vertical).magnitude;
animator.SetFloat("Speed", moveMagnitude * (isSprinting ? 2f : 1f));
}
// 只在移动时播放移动音效
bool isMoving = (Mathf.Abs(horizontal) > 0.1f || Mathf.Abs(vertical) > 0.1f);
if (isMoving)
{
if (!audioSource.isPlaying || audioSource.clip != moveSound)
{
audioSource.clip = moveSound;
audioSource.loop = true;
audioSource.pitch = isSprinting ? 1.2f : 1f; // 冲刺时音调提高
audioSource.Play();
}
}
else
{
if (audioSource.isPlaying && audioSource.clip == moveSound)
{
audioSource.Stop();
}
}
}
public void Jump()
{
// 地面检测
isGrounded = Physics.Raycast(transform.position, Vector3.down, groundCheckDistance);
if (isGrounded)
{
jumpcount = 1; // 重置跳跃次数
}
// 按下空格键且有跳跃次数时
if (Input.GetKeyDown(KeyCode.Space) && jumpcount > 0)
{
// 执行跳跃
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
jumpcount--;
// 播放跳跃音效(确保只播放一次)
if (jumpSound != null)
{
audioSource.PlayOneShot(jumpSound); // 使用PlayOneShot确保每次按键只播一次
}
}
}
public void view()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
verticalRotation -= mouseY;
verticalRotation = Mathf.Clamp(verticalRotation, -upDownRange, upDownRange);
Camera.main.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);
transform.Rotate(0, mouseX, 0);
}
public void Respawn()
{
Debug.Log("尝试复活...");
if (SavePoint.currentSavePoint != null)
{
Debug.Log($"找到存档点: {SavePoint.currentSavePoint.position}");
transform.position = SavePoint.currentSavePoint.position;
health = 100;
if (healthSlider != null)
{
healthSlider.value = health;
}
// 调试音效状态
Debug.Log($"复活音效状态 - 已分配: {respawnSound != null}, 音频源正在播放: {audioSource.isPlaying}");
if (respawnSound != null)
{
audioSource.Stop();
Debug.Log("停止所有音效");
audioSource.PlayOneShot(respawnSound);
Debug.Log("应已播放复活音效");
}
else
{
Debug.LogError("复活音效未分配!");
}
if (respawnText != null)
{
respawnText.enabled = true;
StartCoroutine(HideRespawnTextAfterDelay(3f));
}
}
else
{
Debug.LogError("没有可用的存档点!");
}
}
void TakeFallDamage(float fallDistance)
{
int damage = Mathf.FloorToInt((fallDistance - fallDamageThreshold) * fallDamageMultiplier);
health = Mathf.Max(0, health - damage);
}
IEnumerator HideRespawnTextAfterDelay(float delay)
{
yield return new WaitForSeconds(delay);
if (respawnText != null)
{
respawnText.enabled = false;
}
}
}
人物声音
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimedAudioPlayer : MonoBehaviour
{
[Header("音频设置")]
public List<AudioClip> audioClips = new List<AudioClip>(); // 自定义音频数组
public float interval = 15f; // 播放间隔(秒)
public float volume = 1f; // 音量
private AudioSource audioSource;
private float timer;
private int currentIndex = 0;
[Header("播放模式")]
public bool randomPlay = false; // 是否随机播放
void Start()
{
// 确保有AudioSource组件
audioSource = gameObject.GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
}
audioSource.volume = volume;
timer = interval; // 立即播放第一个音频
}
void Update()
{
// 计时器逻辑
timer -= Time.deltaTime;
if (timer <= 0f && audioClips.Count > 0)
{
PlayNextAudio();
timer = interval; // 重置计时器
}
}
void PlayNextAudio()
{
if (audioClips.Count == 0) return;
if (randomPlay)
{
currentIndex = Random.Range(0, audioClips.Count);
}
else
{
if (++currentIndex >= audioClips.Count)
{
currentIndex = 0;
}
}
if (currentIndex >= audioClips.Count)
{
currentIndex = 0; // 循环播放
}
if (audioClips[currentIndex] != null)
{
audioSource.clip = audioClips[currentIndex];
audioSource.Play();
Debug.Log($"正在播放音频: {audioClips[currentIndex].name}");
}
else
{
Debug.LogWarning($"音频索引 {currentIndex} 未分配音频剪辑!");
}
currentIndex++;
}
// 添加新音频到数组
public void AddAudioClip(AudioClip newClip)
{
if (newClip != null)
{
audioClips.Add(newClip);
}
}
}
摄像机跟随主角
using UnityEngine;
public class follow : MonoBehaviour
{
public Transform target;
public Camera mainCamera;
void Start()
{
if (target != null && mainCamera != null)
{
mainCamera.transform.SetParent(target);
mainCamera.transform.localPosition = Vector3.zero;
mainCamera.transform.localRotation = Quaternion.identity;
}
}
}
障碍物实现水平方向刷新
using UnityEngine;
public class ObjectSpawnAndMove : MonoBehaviour
{
public float frontBackRange = 10f; // 前后范围
public float spawnInterval = 2f; // 生成间隔
public float moveSpeed = 2f; // 移动速度
public GameObject prefab; // 要生成的物体预制体
public Vector3 spawnStartPosition; // 指定生成的起始位置
public GameObject plane; // 指定的平面物体
public Vector3 planeNormal = Vector3.up; // 指定平面的法线方向
private float leftLimit;
private float rightLimit;
private bool nextIsLeftToRight = true; // 标记下一个物体是否从左到右移动
private void Start()
{
// 获取平面的大小并计算左右边界
if (plane != null)
{
Renderer planeRenderer = plane.GetComponent<Renderer>();
if (planeRenderer != null)
{
float planeWidth = planeRenderer.bounds.size.x;
leftLimit = spawnStartPosition.x - planeWidth / 2;
rightLimit = spawnStartPosition.x + planeWidth / 2;
}
}
// 根据前后范围和间隔距离生成物体
for (float z = spawnStartPosition.z - frontBackRange / 2; z <= spawnStartPosition.z + frontBackRange / 2; z += spawnInterval)
{
Vector3 positionOnPlane = new Vector3(spawnStartPosition.x, spawnStartPosition.y, z);
SpawnObject(positionOnPlane);
nextIsLeftToRight = !nextIsLeftToRight; // 切换下一个物体的移动方向
}
}
private void SpawnObject(Vector3 position)
{
// 确保物体在指定平面上
position = ProjectToPlane(position, planeNormal, spawnStartPosition);
Vector3 startPosition;
bool movingRight;
if (nextIsLeftToRight)
{
startPosition = new Vector3(leftLimit, position.y, position.z);
movingRight = true;
}
else
{
startPosition = new Vector3(rightLimit, position.y, position.z);
movingRight = false;
}
// 生成物体
GameObject newObject = Instantiate(prefab, startPosition, Quaternion.identity);
// 为生成的物体添加移动脚本
newObject.AddComponent<HorizontalMover>().Setup(leftLimit, rightLimit, moveSpeed, movingRight);
}
private Vector3 ProjectToPlane(Vector3 point, Vector3 planeNormal, Vector3 planePoint)
{
Vector3 vectorFromPlanePoint = point - planePoint;
float distanceToPlane = Vector3.Dot(vectorFromPlanePoint, planeNormal);
return point - distanceToPlane * planeNormal;
}
}
public class HorizontalMover : MonoBehaviour
{
private float leftLimit;
private float rightLimit;
private float speed;
private bool movingRight;
public void Setup(float left, float right, float moveSpeed, bool startMovingRight)
{
leftLimit = left;
rightLimit = right;
speed = moveSpeed;
movingRight = startMovingRight;
}
private void Update()
{
if (movingRight)
{
transform.Translate(Vector3.right * speed * Time.deltaTime);
if (transform.position.x >= rightLimit)
{
movingRight = false;
}
}
else
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
if (transform.position.x <= leftLimit)
{
movingRight = true;
}
}
}
}
障碍物实现竖直方向移动
using UnityEngine;
public class VerticalMovement : MonoBehaviour
{
public float moveSpeed = 2f; // 物体移动的速度
public float upperLimit = 2f; // 物体向上移动的临界值
public float lowerLimit = -2f; // 物体向下移动的临界值
private Vector3 initialPosition;
private bool movingUp;
void Start()
{
// 计算随机的 y 坐标作为起始位置,在上下限范围内
float randomY = Random.Range(transform.position.y + lowerLimit, transform.position.y + upperLimit);
initialPosition = new Vector3(transform.position.x, randomY, transform.position.z);
transform.position = initialPosition;
// 随机决定初始移动方向
movingUp = Random.value > 0.5f;
}
void Update()
{
if (movingUp)
{
transform.Translate(Vector3.up * moveSpeed * Time.deltaTime);
if (transform.position.y >= initialPosition.y + upperLimit)
{
movingUp = false;
}
}
else
{
transform.Translate(Vector3.down * moveSpeed * Time.deltaTime);
if (transform.position.y <= initialPosition.y + lowerLimit)
{
movingUp = true;
}
}
}
}
弹跳板
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpringBoard : MonoBehaviour
{
public float jumpHeight = 10f; // 可以弹起的高度
public float jumpDuration = 0.5f; // 弹跳过程持续时间
public AnimationCurve jumpCurve; // 弹跳运动曲线\
public AudioClip bounceSound;
private AudioSource audioSource;
void Start()
{
audioSource = GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
}
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Rigidbody playerRb = other.GetComponent<Rigidbody>();
if (playerRb != null)
{
StartCoroutine(LaunchPlayer(playerRb));
}
if (bounceSound != null)
{
audioSource.PlayOneShot(bounceSound);
}
}
}
IEnumerator LaunchPlayer(Rigidbody playerRb)
{
float timer = 0f;
Vector3 startPos = playerRb.position;
Vector3 targetPos = startPos + Vector3.up * jumpHeight;
// 禁用玩家控制
playerove playerController = playerRb.GetComponent<playerove>();
bool wasEnabled = playerController != null && playerController.enabled;
if (playerController != null) playerController.enabled = false;
// 禁用重力
playerRb.useGravity = false;
playerRb.velocity = Vector3.zero;
while (timer < jumpDuration)
{
timer += Time.deltaTime;
float progress = Mathf.Clamp01(timer / jumpDuration);
float curveValue = jumpCurve.Evaluate(progress);
playerRb.MovePosition(Vector3.Lerp(startPos, targetPos, curveValue));
yield return null;
}
// 恢复设置
if (playerController != null && wasEnabled) playerController.enabled = true;
playerRb.useGravity = true;
}
}
胜利区域
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class VictoryZone : MonoBehaviour
{
[Header("音频设置")]
public AudioClip victoryMusic;
public AudioSource musicAudioSource;
[Header("粒子效果设置")]
public ParticleSystem victoryParticles;
public float particleDuration = 10f;
[Header("UI设置")]
public GameObject victoryTextUI;
public float textDisplayTime = 10f;
[Header("传送设置")]
public Transform respawnPoint;
public float fadeDuration = 1f;
public Image fadeImage;
private bool hasTriggered = false;
private GameObject player;
private AudioSource victoryMusicSource;
void Start()
{
// 确保找到玩家对象
player = GameObject.FindGameObjectWithTag("Player");
if (player == null)
{
Debug.LogError("未找到玩家对象! 请确保玩家有'Player'标签");
}
// 初始化UI状态
if (victoryTextUI != null)
{
victoryTextUI.SetActive(false);
}
// 初始化淡入淡出图像
if (fadeImage != null)
{
fadeImage.gameObject.SetActive(false);
fadeImage.color = Color.clear;
}
else
{
Debug.LogWarning("未分配淡入淡出图像!");
}
}
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player") && !hasTriggered)
{
Debug.Log("玩家进入胜利区域");
hasTriggered = true;
StartCoroutine(VictoryAndTeleportSequence());
}
}
IEnumerator VictoryAndTeleportSequence()
{
Debug.Log("开始胜利序列");
// 1. 播放胜利音乐
if (victoryMusic != null && musicAudioSource != null)
{
GameObject musicPlayer = new GameObject("VictoryMusicPlayer");
victoryMusicSource = musicPlayer.AddComponent<AudioSource>();
victoryMusicSource.clip = victoryMusic;
victoryMusicSource.Play();
}
else
{
Debug.LogWarning("音乐或音频源未设置!");
}
// 2. 播放粒子效果
if (victoryParticles != null)
{
Debug.Log("播放粒子效果");
victoryParticles.Play();
}
else
{
Debug.LogWarning("粒子系统未设置!");
}
// 3. 显示胜利文本
if (victoryTextUI != null)
{
Debug.Log("显示胜利文本");
victoryTextUI.SetActive(true);
}
else
{
Debug.LogWarning("胜利文本UI未设置!");
}
// 4. 等待显示时间
Debug.Log($"等待 {textDisplayTime} 秒");
yield return new WaitForSeconds(textDisplayTime);
// 5. 隐藏胜利文本
if (victoryTextUI != null)
{
victoryTextUI.SetActive(false);
}
// 6. 执行传送
yield return StartCoroutine(TeleportPlayer());
if (victoryMusicSource != null && victoryMusicSource.isPlaying)
{
victoryMusicSource.Stop();
Destroy(victoryMusicSource.gameObject);
}
// 7. 重置触发状态
hasTriggered = false;
Debug.Log("胜利序列完成");
}
IEnumerator TeleportPlayer()
{
Debug.Log("开始传送玩家");
// 淡出效果
yield return StartCoroutine(FadeScreen(0, 1));
// 执行传送
if (player != null && respawnPoint != null)
{
Debug.Log($"传送玩家到位置: {respawnPoint.position}");
// 处理CharacterController
CharacterController cc = player.GetComponent<CharacterController>();
if (cc != null)
{
cc.enabled = false;
}
player.transform.position = respawnPoint.position;
player.transform.rotation = respawnPoint.rotation;
if (cc != null)
{
cc.enabled = true;
}
// 重置玩家状态
var playerHealth = player.GetComponent<playerove>();
if (playerHealth != null)
{
if (playerHealth.healthSlider != null)
{
playerHealth.healthSlider.value = 100;
}
}
}
else
{
Debug.LogError("玩家或传送点未设置!");
}
// 淡入效果
yield return StartCoroutine(FadeScreen(1, 0));
Debug.Log("传送完成");
}
IEnumerator FadeScreen(float startAlpha, float endAlpha)
{
if (fadeImage == null) yield break;
fadeImage.gameObject.SetActive(true);
float timer = 0;
while (timer < fadeDuration)
{
timer += Time.deltaTime;
float alpha = Mathf.Lerp(startAlpha, endAlpha, timer / fadeDuration);
fadeImage.color = new Color(0, 0, 0, alpha);
yield return null;
}
if (endAlpha == 0)
{
fadeImage.gameObject.SetActive(false);
}
}
}
存档点
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class LoadGame : MonoBehaviour
{
public playerove player;
private void Start()
{
LoadSaveData();
}
private void LoadSaveData()
{
string path = Application.persistentDataPath + "/save.data";
if (File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
PlayerData data = formatter.Deserialize(stream) as PlayerData;
stream.Close();
if (data.savePointPosition != null)
{
Vector3 savePointPos = new Vector3(data.savePointPosition[0], data.savePointPosition[1], data.savePointPosition[2]);
player.transform.position = savePointPos;
}
else
{
Vector3 position = new Vector3(data.position[0], data.position[1], data.position[2]);
player.transform.position = position;
}
Debug.Log("游戏已读档");
}
else
{
Debug.Log("未找到存档文件");
}
}
}
存档点
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class SavePoint : MonoBehaviour
{
public static Transform currentSavePoint;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
// 更新当前存档点
currentSavePoint = transform;
SaveGame(other.GetComponent<playerove>());
Debug.Log("游戏已存档,当前存档点更新为: " + gameObject.name);
}
}
private void SaveGame(playerove player)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/save.data";
FileStream stream = new FileStream(path, FileMode.Create);
PlayerData data = new PlayerData(player);
if (currentSavePoint != null)
{
data.savePointPosition = new float[3]
{
currentSavePoint.position.x,
currentSavePoint.position.y,
currentSavePoint.position.z
};
}
formatter.Serialize(stream, data);
stream.Close();
}
}
[System.Serializable]
public class PlayerData
{
public float[] position;
public int health;
public float[] savePointPosition;
public PlayerData(playerove player)
{
position = new float[3];
position[0] = player.transform.position.x;
position[1] = player.transform.position.y;
position[2] = player.transform.position.z;
}
}
重开
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class restart : MonoBehaviour
{
// 可移动的物体,例如玩家角色
public GameObject movableObject;
// 指定的目标位置,可通过一个空的 GameObject 来标记
public Transform targetPosition;
// 按钮组件
public Button returnButton;
void Start()
{
// 为按钮的点击事件添加监听器,当点击按钮时调用 MoveToTarget 方法
returnButton.onClick.AddListener(MoveToTarget);
}
// 让可移动的物体移动到指定位置的方法
void MoveToTarget()
{
if (movableObject != null && targetPosition != null)
{
// 将可移动物体的位置设置为目标位置
movableObject.transform.position = targetPosition.position;
}
}
}
背景音乐
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class restart : MonoBehaviour
{
// 可移动的物体,例如玩家角色
public GameObject movableObject;
// 指定的目标位置,可通过一个空的 GameObject 来标记
public Transform targetPosition;
// 按钮组件
public Button returnButton;
void Start()
{
// 为按钮的点击事件添加监听器,当点击按钮时调用 MoveToTarget 方法
returnButton.onClick.AddListener(MoveToTarget);
}
// 让可移动的物体移动到指定位置的方法
void MoveToTarget()
{
if (movableObject != null && targetPosition != null)
{
// 将可移动物体的位置设置为目标位置
movableObject.transform.position = targetPosition.position;
}
}
}
开头的对话框
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour
{
public TextMeshProUGUI dialogueText;
public Button nextButton;
private string[] dialogues = {
"Welcome to the HJC Parkour game",
"Here, you can cultivate your sentiment, listen to music, and relax.",
"Then let's get started."
};
private int currentDialogueIndex = 0;
void Start()
{
// 游戏开始时显示第一条对话
ShowDialogue();
// 为按钮添加点击事件
nextButton.onClick.AddListener(NextDialogue);
}
void ShowDialogue()
{
if (currentDialogueIndex < dialogues.Length)
{
dialogueText.text = dialogues[currentDialogueIndex];
}
else
{
// 对话结束,隐藏按钮和文本
dialogueText.text = "";
nextButton.gameObject.SetActive(false);
Cursor.lockState = CursorLockMode.Locked;
}
}
void NextDialogue()
{
currentDialogueIndex++;
ShowDialogue();
}
}
人物血量UI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthBar : MonoBehaviour
{
public Slider slider;
public void SetMaxHealth(int health)
{
slider.maxValue = health;
slider.value = health;
}
public void SetHealth(int health)
{
slider.value = health;
}
}
鼠标隐藏
using UnityEngine;
using UnityEngine.EventSystems;
public class MouseUnlockOnEsc : MonoBehaviour
{
// 记录鼠标原本的可见状态
private bool originalMouseVisible = true;
// 记录鼠标原本的锁定状态
private bool originalMouseLock = false;
void Start()
{
// 保存初始的鼠标可见和锁定状态
originalMouseVisible = Cursor.visible;
originalMouseLock = Cursor.lockState == CursorLockMode.Locked;
}
void Update()
{
// 检测 Esc 键是否按下
if (Input.GetKeyDown(KeyCode.Escape))
{
// 恢复鼠标的可见性
Cursor.visible = true;
// 将鼠标锁定状态设置为无锁定,允许鼠标自由移动和点击
Cursor.lockState = CursorLockMode.None;
}
// 检测鼠标左键是否按下
if (Input.GetMouseButtonDown(0))
{
// 检查是否点击到了 UI 元素
if (!EventSystem.current.IsPointerOverGameObject())
{
// 隐藏鼠标
Cursor.visible = false;
// 锁定鼠标
Cursor.lockState = CursorLockMode.Locked;
}
}
}
}
说明书UI
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ShowTextOnButtonClick : MonoBehaviour
{
public Button infoButton;
public TextMeshProUGUI instructionText;
void Start()
{
// 游戏开始时隐藏说明文本
instructionText.gameObject.SetActive(false);
// 给按钮的点击事件添加监听,点击按钮时调用 ToggleInstructionText 方法
infoButton.onClick.AddListener(ToggleInstructionText);
}
void ToggleInstructionText()
{
// 获取当前说明文本的显示状态
bool isCurrentlyActive = instructionText.gameObject.activeSelf;
// 切换说明文本的显示状态,若当前显示则隐藏,若当前隐藏则显示
instructionText.gameObject.SetActive(!isCurrentlyActive);
}
}
天色变化
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TimeManager : MonoBehaviour
{
public float dayLength ; // 一天的总时长(秒)
public Light sun; // 太阳光照
public Gradient ambientColorGradient; // 环境光颜色渐变
public Gradient sunlightColorGradient; // 太阳光颜色渐变
public AnimationCurve sunlightIntensityCurve; // 太阳光强度曲线
public float currentTime ; // 当前时间,初始设为白天
public float timeScale = 1f; // 时间流逝速度
void Update()
{
// 更新时间
currentTime += Time.deltaTime * timeScale;
// 确保时间在一天的范围内循环
if (currentTime >= dayLength)
{
currentTime -= dayLength;
}
// 计算当前时间在一天中的比例
float timeRatio = currentTime / dayLength;
// 旋转太阳以模拟昼夜交替
sun.transform.rotation = Quaternion.Euler((timeRatio * 360f) - 90f, 170f, 0f);
// 根据时间比例设置环境光颜色
RenderSettings.ambientLight = ambientColorGradient.Evaluate(timeRatio);
// 根据时间比例设置太阳光颜色和强度
sun.color = sunlightColorGradient.Evaluate(timeRatio);
sun.intensity = sunlightIntensityCurve.Evaluate(timeRatio);
// 只显示秒数
int seconds = Mathf.FloorToInt(currentTime);
}
}
本人小白,这是一次尝试大部分用ai做的游戏,感觉挺好用的~~