This commit is contained in:
wuyanchen 2025-12-10 15:20:19 +08:00
parent 2e038ca10e
commit 61f310ae0d
18 changed files with 204 additions and 57 deletions

View File

@ -1,11 +1,13 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using TMPro; using TMPro;
using Unity.VisualScripting; using Unity.VisualScripting;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch; using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.UI;
using WeChatWASM; using WeChatWASM;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch; using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
@ -42,6 +44,8 @@ public class CameraController : MonoBehaviour
//[SerializeField] private float zoomInertiaDecay = 0.93f; // 惯性衰减系数 //[SerializeField] private float zoomInertiaDecay = 0.93f; // 惯性衰减系数
[SerializeField] private float zoomMin = 2f; [SerializeField] private float zoomMin = 2f;
[SerializeField] private float zoomMax = 30f; [SerializeField] private float zoomMax = 30f;
// Canvas的UI射线检测组件自动获取
public GraphicRaycaster uiRaycaster;
//[SerializeField] private float zoomSnapThreshold = 0.01f; //[SerializeField] private float zoomSnapThreshold = 0.01f;
//[SerializeField] private float zoomSmoothTime = 0.15f; // 新增平滑时间 //[SerializeField] private float zoomSmoothTime = 0.15f; // 新增平滑时间
@ -53,7 +57,7 @@ public class CameraController : MonoBehaviour
// 运行时状态 // 运行时状态
private Camera _cam; private Camera _cam;
private Vector2? _posInput = null; private Vector2 _posInput = Vector2.zero;
private Vector2? _moveInput = null; private Vector2? _moveInput = null;
private Vector2 _zoomInput = Vector2.zero; private Vector2 _zoomInput = Vector2.zero;
private float _rotateInput; private float _rotateInput;
@ -67,9 +71,12 @@ public class CameraController : MonoBehaviour
private float _rotationVelocity; private float _rotationVelocity;
private float _beforeTouchDistance = -1; private float _beforeTouchDistance = -1;
private Vector2? _beforeMoveInput = null; private Vector2? _beforeMoveInput = null;
private int _backgroundLayer = 0;
private int _uiLayer = 0;
private void Awake() private void Awake()
{ {
_backgroundLayer = LayerMask.NameToLayer("Background");
//_uiLayer = LayerMask.NameToLayer("UI");
_cam = GetComponent<Camera>(); _cam = GetComponent<Camera>();
} }
@ -129,7 +136,7 @@ public class CameraController : MonoBehaviour
} }
private void MouseAction_canceled(InputAction.CallbackContext ctx) private void MouseAction_canceled(InputAction.CallbackContext ctx)
{ {
_posInput = null; //_posInput = null;
_beforeMoveInput = null; _beforeMoveInput = null;
_moveInput = null; _moveInput = null;
@ -210,20 +217,36 @@ public class CameraController : MonoBehaviour
//Vector2 mousePos = moveAction.action.ReadValue<Vector2>(); //Vector2 mousePos = moveAction.action.ReadValue<Vector2>();
// 创建射线ScreenPointToRay支持Vector2内部会自动处理z轴为0 // 创建射线ScreenPointToRay支持Vector2内部会自动处理z轴为0
if (EventSystem.current.IsPointerOverGameObject())
{
return true;
}
return false;
//Ray ray = _cam.ScreenPointToRay(_moveInput);
//// ÉäÏß¼ì²â£¨¼ì²âUI²ã£© if (uiRaycaster != null)
//if (Physics.Raycast(ray, out RaycastHit hit, 100f, LayerMask.GetMask("UI"))) {
//{ // 第一步先检测UI
// //enabled = false; PointerEventData pointerData = new PointerEventData(EventSystem.current);
// //StartCoroutine(EnableAfterDelay(0.1f)); pointerData.position = _posInput;
// return false; List<RaycastResult> uiResults = new List<RaycastResult>();
//} uiRaycaster.Raycast(pointerData, uiResults);
if (uiResults.Count > 0)
{
return true; // 有UI则不检测3D
}
}
Ray ray = _cam.ScreenPointToRay(_posInput);
if (Physics.Raycast(ray, out RaycastHit hit, 100f))
{
if (hit.collider.gameObject.layer == _backgroundLayer)
{
//enabled = false;
//StartCoroutine(EnableAfterDelay(0.1f));
return false;
}
}
return false;
// 射线检测检测U
//return true; //return true;
} }
@ -293,7 +316,7 @@ public class CameraController : MonoBehaviour
//_zoomInput.Set(0, 0); //_zoomInput.Set(0, 0);
//_posInput.Value.Set(0, 0); //_posInput.Value.Set(0, 0);
} }
float touchDistance = Vector2.Distance(_posInput.Value, _zoomInput); float touchDistance = Vector2.Distance(_posInput, _zoomInput);
if (_beforeTouchDistance == -1) if (_beforeTouchDistance == -1)
{ {
_beforeTouchDistance = touchDistance; _beforeTouchDistance = touchDistance;
@ -351,9 +374,9 @@ public class CameraController : MonoBehaviour
// 回调方法实现 // 回调方法实现
private void OnMovePerformed(InputAction.CallbackContext ctx) private void OnMovePerformed(InputAction.CallbackContext ctx)
{ {
_posInput = ctx.ReadValue<Vector2>();
if (_isPressDown) if (_isPressDown)
{ {
_posInput = ctx.ReadValue<Vector2>();
if (_beforeMoveInput == null) if (_beforeMoveInput == null)
{ {
_beforeMoveInput = _posInput; _beforeMoveInput = _posInput;
@ -367,7 +390,7 @@ public class CameraController : MonoBehaviour
private void OnMoveCanceled(InputAction.CallbackContext ctx) private void OnMoveCanceled(InputAction.CallbackContext ctx)
{ {
_posInput = null; //_posInput = null;
_moveInput = null; _moveInput = null;
_beforeMoveInput = null; _beforeMoveInput = null;

View File

@ -66,6 +66,20 @@ public class Enemy : MonoBehaviour
} }
public void ResetMaterial()
{
var color = _renderer.material.color;
color.a = 1;
_renderer.material.color = color;
}
public void SetAlphaMaterial()
{
var color = _renderer.material.color;
color.a = 0;
_renderer.material.color = color;
}
// Update is called once per frame // Update is called once per frame
void Update() void Update()
{ {
@ -134,7 +148,10 @@ public class Enemy : MonoBehaviour
public void Respawn() public void Respawn()
{ {
AudioTool.AudioSource.PlayOneShot(boomClip); if (boomClip != null)
{
AudioTool.AudioSource.PlayOneShot(boomClip);
}
gameObject.transform.DOKill(true); gameObject.transform.DOKill(true);
Global.LockedEnemies.Remove(GetHashCode()); Global.LockedEnemies.Remove(GetHashCode());
Global.DespawnEnemy(this); Global.DespawnEnemy(this);

View File

@ -9,7 +9,7 @@ using UnityEngine.InputSystem;
public class EnemyManager : MonoBehaviour public class EnemyManager : MonoBehaviour
{ {
public float attackRadius = 5f; public float attackRadius = 5f;
public Transform startLoc; public Transform[] startLoc = new Transform[] { };
public Transform[] pathesLoc = new Transform[] { }; public Transform[] pathesLoc = new Transform[] { };
[Tooltip("每只怪出现的间隔")] [Tooltip("每只怪出现的间隔")]
public float enemyAppearDuration = 0.1f; public float enemyAppearDuration = 0.1f;
@ -42,9 +42,6 @@ public class EnemyManager : MonoBehaviour
/// </summary> /// </summary>
public float enemyMoveSpeed = 1f; public float enemyMoveSpeed = 1f;
[Tooltip("爆炸音效")]
public AudioClip boomClip;
[Tooltip("每波怪的个数")] [Tooltip("每波怪的个数")]
public float initEachEnemyCount = 50; public float initEachEnemyCount = 50;
@ -86,7 +83,7 @@ public class EnemyManager : MonoBehaviour
for (int i = 0; i < initEachEnemyCount; i++) for (int i = 0; i < initEachEnemyCount; i++)
{ {
//var pos = new Vector3(Random.Range(0f, Screen.width), Random.Range(Screen.height + 125f, Screen.height + 353f), _cam.nearClipPlane - _cam.transform.position.z); //var pos = new Vector3(Random.Range(0f, Screen.width), Random.Range(Screen.height + 125f, Screen.height + 353f), _cam.nearClipPlane - _cam.transform.position.z);
SpawnEnemy(Mathf.FloorToInt(Random.value * enemyPrefabList.Length)); var enemyComp = SpawnEnemy(Mathf.FloorToInt(Random.value * enemyPrefabList.Length));
//float duration = Mathf.Max(0.2f, Random.value / _currAttackIndex * 10); //float duration = Mathf.Max(0.2f, Random.value / _currAttackIndex * 10);
//if (i % 5 == 0) //if (i % 5 == 0)
//{ //{
@ -94,6 +91,11 @@ public class EnemyManager : MonoBehaviour
//} //}
//else //else
//{ //{
if (enemyComp != null)
{
yield return null; // Adjust the interval as needed
enemyComp.ResetMaterial();
}
yield return new WaitForSeconds(enemyAppearDuration); // Adjust the interval as needed yield return new WaitForSeconds(enemyAppearDuration); // Adjust the interval as needed
//} //}
} }
@ -102,56 +104,57 @@ public class EnemyManager : MonoBehaviour
} }
} }
public void SpawnEnemy(int enemyIndex) public Enemy SpawnEnemy(int enemyIndex)
{ {
if (enemyIndex < 0 || enemyIndex >= enemyPrefabList.Length) if (enemyIndex < 0 || enemyIndex >= enemyPrefabList.Length)
{ {
Debug.LogError("Invalid enemy index: " + enemyIndex); Debug.LogError("Invalid enemy index: " + enemyIndex);
return; return null;
} }
//var fromPos = _cam.ScreenToWorldPoint(spawnPosition); //var fromPos = _cam.ScreenToWorldPoint(spawnPosition);
//spawnPosition.y = 350;//移动到指定位置 //spawnPosition.y = 350;//移动到指定位置
//var toPos = _cam.ScreenToWorldPoint(spawnPosition); //var toPos = _cam.ScreenToWorldPoint(spawnPosition);
var pos = Vector3.zero; var pos = Vector3.zero;
var enemy = Instantiate(enemyPrefabList[enemyIndex], Vector3.zero, Quaternion.identity); var enemy = Instantiate(enemyPrefabList[enemyIndex], Vector3.zero, Quaternion.identity);
if (startLoc == null && pathesLoc.Length > 0) //if (startLoc.Length == 0 && pathesLoc.Length > 0)
//{
var startPos = startLoc.Last().position;
var bounds = enemy.GetComponentInChildren<Collider>().bounds;
//float angle = Mathf.PI * 2 * Random.value; // 修正角度计算逻辑
float x = Random.Range(0, Screen.width);
float y = Screen.height + 100;
pos = new Vector3(x, y, _cam.transform.position.z);
bool isLeft = pos.x < Screen.width * 0.5f;
pos = _cam.ScreenToWorldPoint(pos);
pos.y = pathesLoc.Last().position.y;
pos.z = startPos.z;
//往中聚拢怪物尺寸的长度
if (isLeft)
{ {
var bounds = enemy.GetComponentInChildren<Collider>().bounds; pos.x += bounds.size.magnitude * 0.5f;
//float angle = Mathf.PI * 2 * Random.value; // 修正角度计算逻辑
float x = Random.Range(0, Screen.width);
float y = Screen.height + 100;
pos = new Vector3(x, y, 0);
bool isLeft = pos.x < Screen.width * 0.5f;
pos = _cam.ScreenToWorldPoint(pos);
pos.y = pathesLoc.Last().position.y;
//往中聚拢怪物尺寸的长度
if (isLeft)
{
pos.x += bounds.size.magnitude * 0.5f;
}
else
{
pos.x -= bounds.size.magnitude * 0.5f;
}
//pathesLoc.Last().position + new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * attackRadius;
} }
else else
{ {
pos = startLoc.position; pos.x -= bounds.size.magnitude * 0.5f;
} }
//pathesLoc.Last().position + new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * attackRadius;
//}
//else
//{
// pos = startLoc[Random.Range(0, startLoc.Length)].position;
//}
enemy.position = pos; enemy.position = pos;
var enemyComp = enemy.GetComponent<Enemy>(); var enemyComp = enemy.GetComponent<Enemy>();
enemy.eulerAngles = new Vector3(enemy.eulerAngles.x + enemyComp.addEulerX, enemy.eulerAngles.y + 180, enemy.eulerAngles.z); enemy.eulerAngles = new Vector3(enemy.eulerAngles.x + enemyComp.addEulerX, enemy.eulerAngles.y + 180, enemy.eulerAngles.z);
//Debug.Log(enemy.eulerAngles); //Debug.Log(enemy.eulerAngles);
enemyComp.boomClip = boomClip;
Global.Enemies.Add(enemyComp); Global.Enemies.Add(enemyComp);
// 初始化时将物体移动到最近的NavMesh点 // 初始化时将物体移动到最近的NavMesh点
NavMeshHit initHit; NavMeshHit initHit;
if (NavMesh.SamplePosition(enemy.position, out initHit, 8.0f, NavMesh.AllAreas)) if (NavMesh.SamplePosition(enemy.position, out initHit, 8.0f, NavMesh.AllAreas))
{ {
transform.position = initHit.position; enemy.position = initHit.position;
} }
else else
{ {
@ -162,6 +165,8 @@ public class EnemyManager : MonoBehaviour
destPos = new Vector3(enemy.position.x, destPos.y, destPos.z); destPos = new Vector3(enemy.position.x, destPos.y, destPos.z);
ToDestination(enemyComp, destPos); ToDestination(enemyComp, destPos);
enemyComp.SetAlphaMaterial();
return enemyComp;
//enemy.DOMove(toPos, enemyMoveSpeed) //enemy.DOMove(toPos, enemyMoveSpeed)
// .SetEase(Ease.Linear) // 强制匀速,无加速减速 // .SetEase(Ease.Linear) // 强制匀速,无加速减速
// .SetSpeedBased(); // 标记为可回收,完成后回收到池; // 关键:将第二个参数视为“速度”而非“时间” // .SetSpeedBased(); // 标记为可回收,完成后回收到池; // 关键:将第二个参数视为“速度”而非“时间”

View File

@ -26,7 +26,10 @@ public class Shot : MonoBehaviour
public Transform turret; public Transform turret;
public Transform gun; public Transform gun;
[Tooltip("发射音效")]
public AudioClip shotAudioClip; public AudioClip shotAudioClip;
[Tooltip("击中音效")]
public AudioClip hitAudioClip;
[Tooltip("发射时间间隔")] [Tooltip("发射时间间隔")]
public float shotDuration = 0.2f; public float shotDuration = 0.2f;
[Tooltip("连发发射时间间隔")] [Tooltip("连发发射时间间隔")]
@ -263,6 +266,12 @@ public class Shot : MonoBehaviour
if (bulletObj != null) if (bulletObj != null)
{ {
// 10. 播放音效
if (!isNextLineShot && shotAudioClip != null)
{
AudioTool.AudioSource.PlayOneShot(shotAudioClip);
}
//// 1. 强制重置所有状态 //// 1. 强制重置所有状态
//PoolTool.ResetTransform(bulletObj); //PoolTool.ResetTransform(bulletObj);
//PoolTool.ResetTransform(muzzleObj); //PoolTool.ResetTransform(muzzleObj);
@ -383,6 +392,12 @@ public class Shot : MonoBehaviour
//{ //{
//Debug.Log(currentShotCount); //Debug.Log(currentShotCount);
//} //}
if (hitAudioClip != null)
{
AudioTool.AudioSource.PlayOneShot(hitAudioClip);
}
if (currentShotCount <= continueShotCount) if (currentShotCount <= continueShotCount)
{ {
currentShotCount++; currentShotCount++;
@ -455,12 +470,6 @@ public class Shot : MonoBehaviour
// RecycleToPool(muzzleObj, muzzlePool, activeMuzzles); // RecycleToPool(muzzleObj, muzzlePool, activeMuzzles);
// } // }
//}); //});
// 10. ²¥·ÅÒôЧ
if (shotAudioClip != null)
{
AudioTool.AudioSource.PlayOneShot(shotAudioClip);
}
} }
} }

View File

@ -17,7 +17,7 @@ public class AudioTool
{ {
var audioGameObject = new GameObject("GlobalAudioSource"); var audioGameObject = new GameObject("GlobalAudioSource");
_audioSource = audioGameObject.AddComponent<AudioSource>(); _audioSource = audioGameObject.AddComponent<AudioSource>();
_audioSource.volume = 0.5f; _audioSource.volume = 0.33f;
Object.DontDestroyOnLoad(audioGameObject); Object.DontDestroyOnLoad(audioGameObject);
} }
return _audioSource; return _audioSource;

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: XXwe4yOsW3/dMMBzC1jPC8h83tfB/g93jIgfIpggr04FAFQLuAPZ0Zs=
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: Ci4btnj/UH4DjBxU5p6J+WPBPbfw7HxW6JXXY/7jYllQhbqnUu3Njos=
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: WXhK4y2lVi5Q0Jdo2o+m5LxOyeR6OArhUoJErsePDCNFMEng5r0pKRM=
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: XnwdvCquUnivlXs1Aa5DYb7VjTp1uY5iAqEzAYDUnByAilWQt8+6k8w=
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: By9J436tWy7lbhGkTTIXOHBXpALErfz7Pn4aW0E71gUoXPLKJD0ji/k=
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: CywfsiKrVy0pKKtI4ZwffkOrnjFk5/3iMWZO/ydd05n7d8B0u6Q8wzI=
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant: