Time.deltaTime 的平均值在0.1-0.2左右

本文讨论了Unity引擎中Time.deltaTime参数的变化范围及其应用场景。该参数的平均值通常位于0.1到0.2之间,但实际数值可能低至0.03或高达0.3。
using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; using Kinect = Windows.Kinect; public class WarmUpGame : MonoBehaviour { public enum ExerciseAction { ArmRaise, // 举双手 HeadShake, // 摇头 LegLift, // 抬脚 Jump, // 跳跃 RightBend, // 向右弯腰 Bow, // 鞠躬 Run, // 原地跑步 Squat // 深蹲 } private KinectManager _kinectManager; private ExerciseAction _currentAction; private int _actionCount = 0; private int _score = 0; public float _timeRemaining = 30f; private bool _gameActive = true; public Animator _animator; [Header("UI Elements")] public Text actionText; public Text countText; public Text scoreText; public Text timerText; public Text debugText; // 新增调试信息显示 [Header("Animation Settings")] public float animationSpeed = 1.0f; [Header("Game Settings")] public int targetCount = 5; public float actionThreshold = 0.6f; public int validationFrames = 10; // 动作确认所需连续帧 // 新增灵敏度参 [Header("Sensitivity Settings")] public float headShakeSensitivity = 0.3f; public float legLiftSensitivity = 0.7f; public float jumpSensitivity = 0.5f; public float bendSensitivity = 0.5f; [Header("Sensitivity Settings")] public float armRaiseAngleThreshold = 150f; // 手臂伸直角度阈值 public float bowAngleThreshold = 30f; // 鞠躬角度阈值 public float armHeightThreshold = 0.2f; // 手臂高度阈值(相对于头部) public float headDropThreshold = 0.15f; // 头部下降阈值 public float spineBendThreshold = 25f; // 脊柱弯曲阈值 // 动作状态跟踪 private Dictionary<ExerciseAction, bool> _actionValidated = new Dictionary<ExerciseAction, bool>(); private Dictionary<ExerciseAction, int> _validationCounters = new Dictionary<ExerciseAction, int>(); private Queue<Vector3> _headPositionHistory = new Queue<Vector3>(); private Vector3 _lastSpineBasePosition; private float _lastHeadRotation; private bool _lastLegLiftState; private Vector3 _initialHipPosition; private Vector3 _lastFootPosition; private Vector3 _initialHeadPosition; private Vector3 _initialSpineShoulderPosition; private Vector3 _initialSpineBasePosition; public bool feetOffGround; private float _lastBowDetectionTime; public float jumpHeight; public float headDrop; public float shoulderHipHeightDiff; private float _initialSpineLength; public float spineAngle; public Vector3 spineBase; void Start() { _kinectManager = KinectManager.Instance; if (_animator != null) _animator.speed = animationSpeed; InitializeActionSystems(); // 记录初始位置 if (_kinectManager.IsUserDetected()) { long userId = _kinectManager.GetUserIdByIndex(0); _initialHeadPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Head); _initialSpineShoulderPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineShoulder); _initialSpineBasePosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); _initialHipPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); } if (_kinectManager.IsUserDetected()) { long userId = _kinectManager.GetUserIdByIndex(0); _lastSpineBasePosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); } _lastSpineBasePosition = Vector3.zero; _initialHipPosition = Vector3.zero; _initialHeadPosition = Vector3.zero; // 强制初始化计器 foreach (var key in _validationCounters.Keys.ToList()) { _validationCounters[key] = 0; } StartNewAction(); StartCoroutine(GameTimer()); } void InitializeActionSystems() { foreach (ExerciseAction action in System.Enum.GetValues(typeof(ExerciseAction))) { _actionValidated[action] = false; _validationCounters[action] = 0; } } IEnumerator GameTimer() { while (_timeRemaining > 0 && _gameActive) { yield return new WaitForSeconds(1f); _timeRemaining--; timerText.text = $"时间: {_timeRemaining}s"; } if (_gameActive) { _gameActive = false; actionText.text = "游戏结束!"; if (_animator != null) _animator.enabled = false; } } void StartNewAction() { List<ExerciseAction> availableActions = new List<ExerciseAction>((ExerciseAction[])System.Enum.GetValues(typeof(ExerciseAction))); if (availableActions.Count > 1 && availableActions.Contains(_currentAction)) availableActions.Remove(_currentAction); _lastBowDetectionTime = Time.time - 2f; // 确保可以立即检测 _currentAction = availableActions[Random.Range(0, availableActions.Count)]; _actionCount = 0; countText.text = $"0/{targetCount}"; actionText.text = GetActionName(_currentAction); // 重置所有验证状态 foreach (var key in new List<ExerciseAction>(_validationCounters.Keys)) { _validationCounters[key] = 0; _actionValidated[key] = false; } // 重置初始位置记录 if (_kinectManager.IsUserDetected()) { long userId = _kinectManager.GetUserIdByIndex(0); _initialHipPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.HipLeft); } if (_animator != null) PlayActionAnimation(_currentAction); if (_kinectManager.IsUserDetected()) { long userId = _kinectManager.GetUserIdByIndex(0); Vector3 spineShoulder = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineShoulder); Vector3 spineBase = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); // 记录初始脊柱长度 _initialSpineLength = Vector3.Distance(spineShoulder, spineBase); } } void PlayActionAnimation(ExerciseAction action) { foreach (ExerciseAction a in System.Enum.GetValues(typeof(ExerciseAction))) { _animator.SetBool(a.ToString(), false); } _animator.SetBool(action.ToString(), true); } string GetActionName(ExerciseAction action) { switch (action) { case ExerciseAction.ArmRaise: return "举双手"; case ExerciseAction.HeadShake: return "摇头"; case ExerciseAction.LegLift: return "抬左脚"; case ExerciseAction.Jump: return "跳跃"; case ExerciseAction.RightBend: return "向右弯腰"; case ExerciseAction.Bow: return "鞠躬"; case ExerciseAction.Run: return "原地跑步"; case ExerciseAction.Squat: return "深蹲"; default: return "未知动作"; } } void Update() { if (!_gameActive || !_kinectManager.IsUserDetected()) { debugText.text = "等待用户..."; return; } long userId = _kinectManager.GetUserIdByIndex(0); UpdateActionDetection(userId); // 显示当前动作的调试信息 ShowDebugInfo(userId); } void UpdateActionDetection(long userId) { bool actionDetected = false; switch (_currentAction) { case ExerciseAction.ArmRaise: actionDetected = ValidateArmRaise(userId); break; case ExerciseAction.HeadShake: actionDetected = ValidateHeadShake(userId); break; case ExerciseAction.LegLift: actionDetected = ValidateLegLift(userId); break; case ExerciseAction.Jump: actionDetected = ValidateJump(userId); break; case ExerciseAction.RightBend: actionDetected = ValidateRightBend(userId); break; case ExerciseAction.Bow: actionDetected = ValidateBow(userId); break; case ExerciseAction.Run: actionDetected = ValidateRunning(userId); break; case ExerciseAction.Squat: actionDetected = ValidateSquat(userId); break; } if (actionDetected) { if (!_actionValidated[_currentAction]) { _actionCount++; countText.text = $"{_actionCount}/{targetCount}"; _actionValidated[_currentAction] = true; if (_actionCount >= targetCount) { _score += 50; scoreText.text = $"分: {_score}"; StartNewAction(); } } } else { _actionValidated[_currentAction] = false; } } // 显示调试信息 void ShowDebugInfo(long userId) { string debugInfo = $"当前动作: {_currentAction}\n"; switch (_currentAction) { case ExerciseAction.HeadShake: Vector3 headPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Head); Vector3 neckPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Neck); float headRotation = Vector3.Angle(Vector3.up, headPosition - neckPosition); debugInfo += $"头部旋转: {headRotation:F1}°\n阈值: >20°"; break; case ExerciseAction.LegLift: Vector3 hipLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.HipLeft); Vector3 ankleLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.AnkleLeft); float liftHeight = ankleLeft.y - hipLeft.y; debugInfo += $"抬腿高度: {liftHeight:F2}m\n阈值: >{legLiftSensitivity:F2}m"; break; case ExerciseAction.Jump: // 强制获取实时据 Vector3 spineBaseNow = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); Vector3 initialHipNow = _initialHipPosition; debugInfo = $"当前脊柱Y: {spineBaseNow.y:F3}m | 初始Y: {initialHipNow.y:F3}m\n"; debugInfo += $"高度差: {jumpHeight:F3}m | 离地: {feetOffGround}\n"; // 添加速度显示 if (_lastSpineBasePosition != Vector3.zero) { Vector3 velocity = (spineBaseNow - _lastSpineBasePosition) / Time.deltaTime; debugInfo += $"速度Y: {velocity.y:F2}m/s\n"; } debugInfo += $"计器: {_validationCounters[_currentAction]}/2"; break; case ExerciseAction.RightBend: Vector3 shoulderCenter = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineShoulder); Vector3 hipCenter = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); Vector3 spineVector = hipCenter - shoulderCenter; float bendAngle = Vector3.Angle(spineVector, Vector3.up); debugInfo += $"弯曲角度: {bendAngle:F1}°\n阈值: >20°"; break; case ExerciseAction.Bow: Vector3 spineShoulder = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineShoulder); spineBase = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); Vector3 headPos = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Head); Vector3 neck = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Neck); float spineLength = Vector3.Distance(spineShoulder, spineBase); float compression = 1 - (spineLength / _initialSpineLength); debugInfo = $"脊柱弯曲: {spineAngle:F1}°\n"; debugInfo += $"头降量: {(neck.y - headPos.y):F2}m\n"; debugInfo += $"脊柱压缩: {compression * 100:F1}%"; break; } debugText.text = debugInfo; } // ===== 改进的动作检测算法 ===== private bool ValidateArmRaise(long userId) { // 获取必要关节位置 Vector3 leftHand = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.HandLeft); Vector3 rightHand = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.HandRight); Vector3 leftShoulder = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.ShoulderLeft); Vector3 rightShoulder = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.ShoulderRight); Vector3 head = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Head); // 简化的举双手检测 - 只关注手部是否高于肩膀 bool leftHandRaised = leftHand.y > leftShoulder.y + 0.1f; // 手高于肩膀10cm bool rightHandRaised = rightHand.y > rightShoulder.y + 0.1f; // 备选方案:手部高于头部 // bool leftHandRaised = leftHand.y > head.y; // bool rightHandRaised = rightHand.y > head.y; // 双手举起即视为成功 return leftHandRaised && rightHandRaised; } private bool ValidateHeadShake(long userId) { Vector3 headPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Head); Vector3 neckPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Neck); // 计算头部旋转角度 Vector3 headDirection = headPosition - neckPosition; float currentRotation = Vector3.Angle(Vector3.up, headDirection); // 记录历史旋转 _headPositionHistory.Enqueue(headPosition); if (_headPositionHistory.Count > 30) _headPositionHistory.Dequeue(); // 检查旋转变化 bool rotationDetected = false; if (_headPositionHistory.Count > 10) { Vector3[] positions = _headPositionHistory.ToArray(); float minAngle = float.MaxValue; float maxAngle = float.MinValue; for (int i = 0; i < positions.Length; i++) { Vector3 dir = positions[i] - neckPosition; float angle = Vector3.Angle(Vector3.up, dir); if (angle < minAngle) minAngle = angle; if (angle > maxAngle) maxAngle = angle; } rotationDetected = (maxAngle - minAngle) > 20f; // 20度变化阈值 } // 增加直接旋转检测 bool directRotation = currentRotation > 20f || Mathf.Abs(currentRotation - _lastHeadRotation) > 15f; _lastHeadRotation = currentRotation; return rotationDetected || directRotation; } // 改进的抬腿检测 private bool ValidateLegLift(long userId) { Vector3 hipLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.HipLeft); Vector3 kneeLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.KneeLeft); Vector3 ankleLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.AnkleLeft); // 计算腿部角度(髋--踝) float legAngle = Vector3.Angle(kneeLeft - hipLeft, ankleLeft - kneeLeft); // 计算抬腿高度 float liftHeight = ankleLeft.y - hipLeft.y; // 检测腿部运动状态变化 bool isLifted = liftHeight > legLiftSensitivity && legAngle < 140f; bool stateChanged = isLifted && !_lastLegLiftState; _lastLegLiftState = isLifted; return stateChanged; } // 改进的跳跃检测 private bool ValidateJump(long userId) { // 据验证代码... // 初始化上一帧位置(首次执行时) if (_lastSpineBasePosition == Vector3.zero) { _lastSpineBasePosition = spineBase; _initialHipPosition = spineBase; // 同步初始化 return false; } // 计算速度(添加除零保护) float deltaTime = Mathf.Max(Time.deltaTime, 0.001f); // 防止除零 Vector3 velocity = (spineBase - _lastSpineBasePosition) / deltaTime; _lastSpineBasePosition = spineBase; // 动态更新初始位置 if (_validationCounters[_currentAction] == 0) { _initialHipPosition = spineBase; } // 高度计算(添加容错) jumpHeight = Mathf.Max(spineBase.y - _initialHipPosition.y, 0); // 离地检测(使用绝对高度差) Vector3 footLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.FootLeft); Vector3 footRight = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.FootRight); feetOffGround = (footLeft.y > _initialHipPosition.y + 0.1f) || (footRight.y > _initialHipPosition.y + 0.1f); // ==== 调试输出强制显示 ==== Debug.Log($"跳跃检测: 高度={jumpHeight} 速度Y={velocity.y} 离地={feetOffGround}"); // 检测逻辑(简化版) if (jumpHeight > 0.05f && feetOffGround) { _validationCounters[_currentAction]++; if (_validationCounters[_currentAction] >= 2) // 降低帧要求 { _validationCounters[_currentAction] = 0; return true; } } else { _validationCounters[_currentAction] = 0; } return false; } // 改进的右弯检测 private bool ValidateRightBend(long userId) { Vector3 shoulderCenter = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineShoulder); Vector3 hipCenter = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); Vector3 shoulderLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.ShoulderLeft); Vector3 shoulderRight = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.ShoulderRight); // 计算躯干倾斜角度 Vector3 spineVector = hipCenter - shoulderCenter; float bendAngle = Vector3.Angle(spineVector, Vector3.up); // 计算肩膀高度差 float shoulderHeightDiff = shoulderLeft.y - shoulderRight.y; // 使用复合条件提高准确性 return (bendAngle < 148f ); } private bool ValidateBow(long userId) { // 获取当前关节位置 Vector3 headPos = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Head); Vector3 spineShoulder = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineShoulder); Vector3 spineMid = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineMid); Vector3 spineBase = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); Vector3 neck = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.Neck); // 1. 计算脊柱弯曲角度(关键指标) Vector3 upperSpine = spineShoulder - spineMid; Vector3 lowerSpine = spineBase - spineMid; spineAngle = Vector3.Angle(upperSpine, lowerSpine); // 2. 相对头部下降量(基于颈部参考) float headDrop = neck.y - headPos.y; // 3. 脊柱长度变化检测 float spineLength = Vector3.Distance(spineShoulder, spineBase); float spineCompression = 1 - (spineLength / _initialSpineLength); // 检测条件(优先脊柱角度) bool isBowing = spineAngle < 140f || // 脊柱弯曲角度阈值 headDrop > 0.15f || // 头部相对下降量 spineCompression > 0.1f; // 脊柱压缩率 // 冷却时间检查 bool canDetectAgain = (Time.time - _lastBowDetectionTime) > 0.5f; if (isBowing && canDetectAgain) { _lastBowDetectionTime = Time.time; return true; } return false; } private bool ValidateRunning(long userId) { Vector3 ankleLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.AnkleLeft); Vector3 ankleRight = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.AnkleRight); // 检测腿部交替运动 float verticalMovement = Mathf.Abs(ankleLeft.y - ankleRight.y); bool legsMoving = verticalMovement > actionThreshold * 0.5f; // 位置变化检测 if (_lastFootPosition != Vector3.zero) { float positionChange = Vector3.Distance(ankleLeft, _lastFootPosition); legsMoving |= positionChange > actionThreshold * 0.2f; } _lastFootPosition = ankleLeft; return legsMoving; } private bool ValidateSquat(long userId) { Vector3 hipLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.HipLeft); Vector3 kneeLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.KneeLeft); Vector3 ankleLeft = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.AnkleLeft); // 计算大腿-小腿夹角 Vector3 thighVector = kneeLeft - hipLeft; Vector3 shinVector = ankleLeft - kneeLeft; float kneeAngle = Vector3.Angle(thighVector, shinVector); return kneeAngle < 100f; } } 使用以上代碼,脊柱压缩變成了-infinity
12-09
using System.Collections; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; public enum Battle { Start, PlayerTurn, EnemyTurn, Lose, Win } public class BattleSystem : MonoBehaviour { public enum gameover{win,lose} public Battle State; public float typingSpeed = 0.05f; private bool isTyping = false; public GameObject PlayerPrefeb; public GameObject EnemyPrefeb; public Transform PlayerPosition; public Transform EnemyPosition; private Playermessage playerpeople; private Enemymessage emenypeople; public EnemyBattleHUD enemyHUD; public PlayerBattleHUD playerHUD; public TextMeshProUGUI Text; public GameObject F; public GameObject m; public GameObject back; public GameObject select1; public GameObject select2; public Color flash; private Color Originalcolor; public float Time; public UnityEngine.UI.Image image; public Animator animator; private Camera mainCamera; private Vector3 originalCameraPosition; public UnityEngine.UI.Image attackphoto; public UnityEngine.UI.Image attackphoto2; void Start() { mainCamera = Camera.main; if (mainCamera != null) { originalCameraPosition = mainCamera.transform.localPosition; } State = Battle.Start; StartCoroutine(SetupBattle()); } private IEnumerator SetupBattle() { GameObject player = Instantiate(PlayerPrefeb, PlayerPosition); playerpeople = player.GetComponent<Playermessage>(); GameObject emeny = Instantiate(EnemyPrefeb, EnemyPosition); emenypeople = emeny.GetComponent<Enemymessage>(); playerHUD.SetHUD(playerpeople); enemyHUD.SetHUD(emenypeople); // 显示开场信息(带打字效果) yield return StartCoroutine(TypeText("Let me feel your power now, don't make me bored^_^", 0.5f)); yield return new WaitForSeconds(0.5f); if (F != null) F.SetActive(false); if (m != null) m.SetActive(true); yield return StartCoroutine(TypeText("I can't lose here", 0.5f)); yield return new WaitForSeconds(0.5f); if (m != null) m.SetActive(false); yield return StartCoroutine(TypeText("--Please consider your decision--", 2f)); State = Battle.PlayerTurn; PlayerTurn(); } // 玩家回合逻辑 private void PlayerTurn() { StartCoroutine(TypeText("Choose your action...", 0f)); } public void OnAttackButton() { if (State != Battle.PlayerTurn) return; StartCoroutine(PlayerAttack()); } private IEnumerator PlayerAttack() { yield return StartCoroutine(TypeText("Get out of my way!!!", 0f)); yield return new WaitForSeconds(1f); attackphoto.gameObject.SetActive(true); // 使用新的伤害计算方法 float damageDealt = player.CalculateDamage(); yield return StartCoroutine(TypeText($"Dealt {damageDealt} damage!", 0f)); yield return new WaitForSeconds(1f); attackphoto.gameObject.SetActive(false); // 调用新的TakeDamage方法 bool IsDead = emenypeople.TakeDamage(damageDealt); enemyHUD.SetHUD(emenypeople); if (IsDead) { State = Battle.Win; EndBattle(); } else { State = Battle.EnemyTurn; StartCoroutine(EnemyTurn()); } } private IEnumerator EnemyTurn() { yield return StartCoroutine(TypeText("Looking my eyes...", 0f)); yield return new WaitForSeconds(0.5f); attackphoto2.gameObject.SetActive(true); yield return new WaitForSeconds(0.5f);animator.SetTrigger("shake"); StartCoroutine(ShakeCamera(0.4f, 0.4f)); Originalcolor = image.color; StartCoroutine(flashboom()); attackphoto2.gameObject.SetActive(false); float damageDealt = GetComponent<SpeacialAttack>().GetDamage(); yield return StartCoroutine(TypeText($"Took {damageDealt} damage!", 0f)); bool IsDead = playerpeople.TakeDamage(); playerHUD.SetHUD(playerpeople); yield return new WaitForSeconds(1f); if (IsDead) { State = Battle.Lose; EndBattle(); } else { State = Battle.PlayerTurn; PlayerTurn(); } } private void EndBattle() { if (State == Battle.Win) { StartCoroutine(TypeText("Victory is mine!", 0f)); EndBattle(true); } else if (State == Battle.Lose) { StartCoroutine(TypeText("Defeat... I'll be back!", 0f)); EndBattle(false); } select1.SetActive(false); select2.SetActive(false); back.SetActive(true); } const string BATTLE_RESULT_KEY = "LastBattleResult"; public void EndBattle(bool isWin) { PlayerPrefs.SetInt(BATTLE_RESULT_KEY, isWin ? 1 : 0); PlayerPrefs.Save(); SceneManager.LoadScene("Traning"); } IEnumerator flashboom()//受击红屏效果 { image.color = flash; yield return new WaitForSeconds(Time); image.color = Originalcolor; } private IEnumerator ShakeCamera(float duration = 0.5f, float magnitude = 0.4f) { Vector3 originalPos = mainCamera.transform.localPosition; float elapsed = 0f; AnimationCurve attenuationCurve = AnimationCurve.EaseInOut(0, 1, 1, 0); while (elapsed < duration) { float attenuation = attenuationCurve.Evaluate(elapsed / duration); float x = Mathf.PerlinNoise(UnityEngine.Time.time * 30f, 0) * 2 - 1; float y = Mathf.PerlinNoise(0, UnityEngine.Time.time * 30f) * 2 - 1; // 5. 应用衰减后的震动幅度 Vector3 shakeOffset = new Vector3(x, y, 0) * magnitude * attenuation; mainCamera.transform.localPosition = originalPos + shakeOffset; // 6. 使用unscaledDeltaTime确保时间精确 elapsed += UnityEngine.Time.unscaledDeltaTime; yield return null; } // 7. 平滑回归原位 float returnDuration = 0.2f; float returnElapsed = 0f; Vector3 currentPos = mainCamera.transform.localPosition; while (returnElapsed < returnDuration) { mainCamera.transform.localPosition = Vector3.Lerp( currentPos, originalPos, returnElapsed / returnDuration ); returnElapsed += UnityEngine.Time.unscaledDeltaTime; yield return null; } mainCamera.transform.localPosition = originalPos; } public IEnumerator TypeText(string sentence, float initialDelay = 0f) { if (Text == null) yield break; isTyping = true; yield return new WaitForSeconds(initialDelay); Text.text = ""; foreach (char letter in sentence.ToCharArray()) { Text.text += letter; yield return new WaitForSeconds(typingSpeed); } isTyping = false; } }using UnityEngine; [System.Serializable] public class Playermessage : MonoBehaviour { // 角色基本属性 [Header("角色属性")] public string characterName; public int level = 100; public float attackPower=50; public float defense; public float maxHealth; [SerializeField] private float currentHealth; // 伤害计算参 [Header("伤害计算")] public float criticalChance = 0.5f; public float criticalMultiplier = 1.5f; public float damageRandomness = 0.1f; // 属性访问器 public float CurrentHealth => currentHealth; // 初始化 private void Start() { currentHealth = maxHealth; } // 伤害计算核心方法 public float CalculateDamage() { // 基础伤害 = 攻击力 * (1 ± 随机波动) float baseDamage = attackPower * (1 + Random.Range(-damageRandomness, damageRandomness)); // 暴击判定 if (Random.value <= criticalChance) { baseDamage *= criticalMultiplier; Debug.Log($"暴击! 伤害: {baseDamage}"); } return Mathf.Max(1, baseDamage); // 确保最小伤害为1 } // 受到伤害处理 public bool TakeDamage(float incomingDamage) { // 实际伤害 = 输入伤害 - 防御力 (至少造成1点伤害) float actualDamage = Mathf.Max(1, incomingDamage - defense); // 更新生命值 currentHealth -= actualDamage; currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth); Debug.Log($"{characterName}受到{actualDamage}点伤害, 剩余生命值: {currentHealth}/{maxHealth}"); // 返回是否死亡 return currentHealth <= 0; } } using UnityEngine; [System.Serializable] public class Enemymessage : MonoBehaviour { // 角色基本属性 [Header("角色属性")] public string characterName; public int level = 1; public float attackPower=50; public float defense; public float maxHealth; [SerializeField] private float currentHealth; // 伤害计算参 [Header("伤害计算")] public float criticalChance = 0.5f; public float criticalMultiplier = 1.5f; public float damageRandomness = 0.1f; // 属性访问器 public float CurrentHealth => currentHealth; // 初始化 private void Start() { currentHealth = maxHealth; } // 伤害计算核心方法 public float CalculateDamage() { // 基础伤害 = 攻击力 * (1 ± 随机波动) float baseDamage = attackPower * (1 + Random.Range(-damageRandomness, damageRandomness)); // 暴击判定 if (Random.value <= criticalChance) { baseDamage *= criticalMultiplier; Debug.Log($"暴击! 伤害: {baseDamage}"); } return Mathf.Max(1, baseDamage); // 确保最小伤害为1 } // 受到伤害处理 public bool TakeDamage(float incomingDamage) { // 实际伤害 = 输入伤害 - 防御力 (至少造成1点伤害) float actualDamage = Mathf.Max(1, incomingDamage - defense); // 更新生命值 currentHealth -= actualDamage; currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth); Debug.Log($"{characterName}受到{actualDamage}点伤害, 剩余生命值: {currentHealth}/{maxHealth}"); // 返回是否死亡 return currentHealth <= 0; } } using UnityEngine; [System.Serializable] public class Enemymessage : MonoBehaviour { // 角色基本属性 [Header("角色属性")] public string characterName; public int level = 1; public float attackPower=50; public float defense; public float maxHealth; [SerializeField] private float currentHealth; // 伤害计算参 [Header("伤害计算")] public float criticalChance = 0.5f; public float criticalMultiplier = 1.5f; public float damageRandomness = 0.1f; // 属性访问器 public float CurrentHealth => currentHealth; // 初始化 private void Start() { currentHealth = maxHealth; } // 伤害计算核心方法 public float CalculateDamage() { // 基础伤害 = 攻击力 * (1 ± 随机波动) float baseDamage = attackPower * (1 + Random.Range(-damageRandomness, damageRandomness)); // 暴击判定 if (Random.value <= criticalChance) { baseDamage *= criticalMultiplier; Debug.Log($"暴击! 伤害: {baseDamage}"); } return Mathf.Max(1, baseDamage); // 确保最小伤害为1 } // 受到伤害处理 public bool TakeDamage(float incomingDamage) { // 实际伤害 = 输入伤害 - 防御力 (至少造成1点伤害) float actualDamage = Mathf.Max(1, incomingDamage - defense); // 更新生命值 currentHealth -= actualDamage; currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth); Debug.Log($"{characterName}受到{actualDamage}点伤害, 剩余生命值: {currentHealth}/{maxHealth}"); // 返回是否死亡 return currentHealth <= 0; } }我现在更新了后面两个脚本,帮我修改BattleSystem,写出BattleSystem全代码
07-31
using System.Collections.Generic; using UnityEngine; using Valve.VR; public class VrControllerInput : MonoBehaviour { public SteamVR_Input_Sources handType; public ArrowDirection currentDirection; public Transform referenceTransform; // 参考坐标系(通常为摄像机或玩家头部) [Header("调试设置")] public bool showDebugRays = true; public float debugRayLength = 2f; [Header("方向阈值")] [Range(0, 90)] public float upThreshold = 30f; [Range(0, 90)] public float downThreshold = 30f; [Header("移动检测设置")] public float movementThreshold = 0.05f; // 移动检测灵敏度 public int movementHistorySize = 10; // 存储的位置历史量 private Queue<Vector3> positionHistory = new Queue<Vector3>(); private Vector3 lastPosition; void Start() { lastPosition = transform.position; // 初始化位置历史 for (int i = 0; i < movementHistorySize; i++) { positionHistory.Enqueue(transform.position); } } void Update() { // 更新位置历史 positionHistory.Enqueue(transform.position); if (positionHistory.Count > movementHistorySize) { positionHistory.Dequeue(); } // 更新最后位置 lastPosition = transform.position; if (referenceTransform == null) referenceTransform = Camera.main.transform; // 获取控制器在参考坐标系中的方向 Vector3 localForward = referenceTransform.InverseTransformDirection(transform.forward); // 计算水平面上的角度 float horizontalAngle = Mathf.Atan2(localForward.x, localForward.z) * Mathf.Rad2Deg; // 计算垂直面上的角度(与水平面的夹角) Vector3 horizontalForward = new Vector3(localForward.x, 0, localForward.z).normalized; float verticalAngle = Vector3.Angle(horizontalForward, localForward); bool isDownward = localForward.y < 0; // 调试显示 if (showDebugRays) { Debug.DrawRay(transform.position, transform.forward * debugRayLength, Color.blue, 0.1f); Debug.DrawRay(referenceTransform.position, referenceTransform.forward * debugRayLength, Color.green, 0.1f); } // 先判断垂直方向(上下) if (verticalAngle > (90f - downThreshold) && isDownward) { currentDirection = ArrowDirection.Down; // Debug.Log($"检测到向下: 垂直角={verticalAngle}°"); } else if (verticalAngle > (90f - upThreshold) && !isDownward) { currentDirection = ArrowDirection.Up; // Debug.Log($"检测到向上: 垂直角={verticalAngle}°"); } // 再判断水平方向(左右) else { if (Mathf.Abs(horizontalAngle) <= 45f) { // currentDirection = ArrowDirection.Up; // Debug.Log($"检测到向前: 水平角={horizontalAngle}°"); } else if (horizontalAngle > 45f && horizontalAngle <= 135f) { currentDirection = ArrowDirection.Right; // Debug.Log($"检测到向右: 水平角={horizontalAngle}°"); } else if (horizontalAngle < -45f && horizontalAngle >= -135f) { currentDirection = ArrowDirection.Left; // Debug.Log($"检测到向左: 水平角={horizontalAngle}°"); } else { currentDirection = ArrowDirection.Down; // Debug.Log($"检测到向后: 水平角={horizontalAngle}°"); } } } // 添加校准方法(在UI按钮调用) public void CalibrateFrontDirection() { // 重置参考坐标系的前方 referenceTransform.rotation = Quaternion.Euler(0, referenceTransform.eulerAngles.y, 0); Debug.Log("方向已校准"); } public bool GetRecentMovement(ArrowDirection direction, float requiredDistance, float timeWindow) { Vector3 movementVector = CalculateRecentMovement(timeWindow); float movementDistance = movementVector.magnitude; // Debug.Log(movementDistance); if (movementDistance < requiredDistance) return false; // 根据方向判断移动是否符合要求 switch (direction) { case ArrowDirection.Up: return movementVector.z > movementThreshold; case ArrowDirection.Down: return movementVector.z < -movementThreshold; case ArrowDirection.Left: return movementVector.x < -movementThreshold; case ArrowDirection.Right: return movementVector.x > movementThreshold; default: return false; } } // 计算最近时间窗口内的移动向量 private Vector3 CalculateRecentMovement(float timeWindow) { int framesToCheck = Mathf.FloorToInt(timeWindow / Time.deltaTime); framesToCheck = Mathf.Clamp(framesToCheck, 1, movementHistorySize); if (positionHistory.Count < framesToCheck) return Vector3.zero; Vector3[] positions = positionHistory.ToArray(); Vector3 oldestPosition = positions[positions.Length - framesToCheck]; return transform.position - oldestPosition; } } 使用以上代碼偵測htc vive vr 控制器分析方向,上下還是會混亂和不靈敏,請幫忙修改
11-20
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; using UnityEngine.SocialPlatforms.Impl; using UnityEngine.UI; using Kinect = Windows.Kinect; using Random = UnityEngine.Random; public class JumpDetector : MonoBehaviour { private KinectManager _kinectManager; private int _actionCount = 0; private bool _gameActive = true; [Header("UI Elements")] public Text actionText; public Text countText; public Text debugText; [Header("Game Settings")] public int targetCount = 5; public float jumpSensitivity = 0.5f; // 跳跃状态跟踪 private bool _isJumping = false; private bool _isGrounded = true; private Vector3 _initialHipPosition; private Vector3 _lastSpineBasePosition; public bool jump = false; public PlayerController PC; public string prizePath; public string[] prizeLines; void Start() { prizePath = Application.streamingAssetsPath + "/jumpSetting.csv"; string prizeData = File.ReadAllText(prizePath); prizeLines = prizeData.Split('\n'); float.TryParse(prizeLines[0], out jumpSensitivity); _kinectManager = KinectManager.Instance; // 记录初始位置 if (_kinectManager.IsUserDetected()) { long userId = _kinectManager.GetUserIdByIndex(0); _initialHipPosition = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); _lastSpineBasePosition = _initialHipPosition; } actionText.text = "跳躍"; } void Update() { if (!_gameActive || !_kinectManager.IsUserDetected()) { debugText.text = "等待用户..."; return; } long userId = _kinectManager.GetUserIdByIndex(0); UpdateJumpDetection(userId); ShowDebugInfo(userId); } void UpdateJumpDetection(long userId) { if (ValidateJump(userId)) { _actionCount++; countText.text = $"{_actionCount}/{targetCount}"; if (_actionCount >= targetCount) { _actionCount = 0; // 重置计 } } } void ShowDebugInfo(long userId) { if (_kinectManager.IsUserDetected()) { Vector3 spineBaseNow = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); float currentHeight = _initialHipPosition != Vector3.zero ? spineBaseNow.y - _initialHipPosition.y : 0f; debugText.text = $"當前高度: {currentHeight:F3}m\n" + $"跳躍狀態: {(_isJumping ? "空中" : "地面")}\n" + $"跳躍次數: {_actionCount}/{targetCount}"; } } private bool ValidateJump(long userId) { Vector3 spineBaseNow = _kinectManager.GetJointPosition(userId, (int)Kinect.JointType.SpineBase); // 初始化位置 if (_lastSpineBasePosition == Vector3.zero) { _lastSpineBasePosition = spineBaseNow; _initialHipPosition = spineBaseNow; return false; } // 计算高度变化 float currentHeight = spineBaseNow.y - _initialHipPosition.y; // 状态机检测 bool detected = false; if (!_isJumping && currentHeight > jumpSensitivity) { _isJumping = true; // 进入跳跃状态 PC.jump = true; } else if (_isJumping && currentHeight < jumpSensitivity * 0.2f) { _isJumping = false; // 落地状态 detected = true; // 完成一次跳跃 PC.jump = false; } _lastSpineBasePosition = spineBaseNow; return detected; } } unity 使用以上代碼,使用kinect v2 偵測跳躍,希望修改自動更新位置,令玩家在移動后,自動改變_initialHipPosition&_lastSpineBasePosition,不會令玩家在前後移動時跳躍
最新发布
12-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

银狐游戏开发资源2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值