Added enemy system

This commit is contained in:
Hazim Bin Ijaz 2025-08-15 17:16:06 +05:00
parent 5aca87a328
commit b6649ebcec
36 changed files with 17110 additions and 8476 deletions

View File

@ -2,13 +2,18 @@
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000 --- !u!21 &2100000
Material: Material:
serializedVersion: 6 serializedVersion: 8
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: triangle_soft_ADD m_Name: triangle_soft_ADD
m_Shader: {fileID: 211, guid: 0000000000000000f000000000000000, type: 0} m_Shader: {fileID: 211, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _ALPHABLEND_ON m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _ALPHABLEND_ON
m_InvalidKeywords: []
m_LightmapFlags: 0 m_LightmapFlags: 0
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
@ -16,7 +21,8 @@ Material:
stringTagMap: stringTagMap:
RenderType: Transparent RenderType: Transparent
disabledShaderPasses: disabledShaderPasses:
- ALWAYS - GRABPASS
m_LockedProperties:
m_SavedProperties: m_SavedProperties:
serializedVersion: 3 serializedVersion: 3
m_TexEnvs: m_TexEnvs:
@ -32,6 +38,7 @@ Material:
m_Texture: {fileID: 2800000, guid: c21e9846e5a62354d8b9d86c2fa78a7d, type: 3} m_Texture: {fileID: 2800000, guid: c21e9846e5a62354d8b9d86c2fa78a7d, type: 3}
m_Scale: {x: 1, y: 1} m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0} m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats: m_Floats:
- _BlendOp: 0 - _BlendOp: 0
- _BumpScale: 1 - _BumpScale: 1
@ -63,3 +70,4 @@ Material:
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}
- _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} - _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
m_BuildTextureStacks: []

View File

@ -2,13 +2,19 @@
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000 --- !u!21 &2100000
Material: Material:
serializedVersion: 6 serializedVersion: 8
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: snowflake_AB m_Name: snowflake_AB
m_Shader: {fileID: 211, guid: 0000000000000000f000000000000000, type: 0} m_Shader: {fileID: 211, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _ALPHABLEND_ON _FADING_ON m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _ALPHABLEND_ON
- _FADING_ON
m_InvalidKeywords: []
m_LightmapFlags: 0 m_LightmapFlags: 0
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
@ -16,7 +22,8 @@ Material:
stringTagMap: stringTagMap:
RenderType: Transparent RenderType: Transparent
disabledShaderPasses: disabledShaderPasses:
- ALWAYS - GRABPASS
m_LockedProperties:
m_SavedProperties: m_SavedProperties:
serializedVersion: 3 serializedVersion: 3
m_TexEnvs: m_TexEnvs:
@ -32,6 +39,7 @@ Material:
m_Texture: {fileID: 2800000, guid: 26bd50fb644d1134793fe01f633ed367, type: 3} m_Texture: {fileID: 2800000, guid: 26bd50fb644d1134793fe01f633ed367, type: 3}
m_Scale: {x: 1, y: 1} m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0} m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats: m_Floats:
- _BlendOp: 0 - _BlendOp: 0
- _BumpScale: 1 - _BumpScale: 1
@ -63,3 +71,4 @@ Material:
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 6.6666665, b: 0, a: 0} - _SoftParticleFadeParams: {r: 0, g: 6.6666665, b: 0, a: 0}
- _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} - _TintColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 61643333db5430f4c904573c9b0bc075
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 23800000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace Polyart { namespace Polyart {
public class FirstPersonController_Polyart : MonoBehaviour public class FirstPersonController: MonoBehaviour
{ {
public static FirstPersonController_Polyart instance; public static FirstPersonController instance;
public bool CanMove { get; private set; } = true; public bool CanMove { get; private set; } = true;
private bool isSprinting => canSprint && Input.GetKey(sprintKey); private bool isSprinting => canSprint && Input.GetKey(sprintKey);
private bool ShouldJump => Input.GetKeyDown(jumpKey) && characterController.isGrounded; private bool ShouldJump => Input.GetKeyDown(jumpKey) && characterController.isGrounded;

View File

@ -0,0 +1,288 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Polyart {
public class FirstPersonController_PolyartOld : MonoBehaviour
{
public static FirstPersonController_PolyartOld instance;
public bool CanMove { get; private set; } = true;
private bool isSprinting => canSprint && Input.GetKey(sprintKey);
private bool ShouldJump => Input.GetKeyDown(jumpKey) && characterController.isGrounded;
private bool ShouldCrouch => Input.GetKeyDown(crouchKey) && !duringCrouchAnim && characterController.isGrounded;
[Header("Character Options")]
[SerializeField] private bool canSprint = true;
[SerializeField] private bool canJump = true;
[SerializeField] private bool canCrouch = true;
[SerializeField] private bool canHeadBob = true;
[SerializeField] private bool canInteract = true;
[SerializeField] private bool useFootsteps = true;
[Header("Controls")]
[SerializeField] private KeyCode sprintKey = KeyCode.LeftShift;
[SerializeField] private KeyCode jumpKey = KeyCode.Space;
[SerializeField] private KeyCode crouchKey = KeyCode.LeftControl;
[SerializeField] private KeyCode interactKey = KeyCode.E;
[Header("Interaction")]
[SerializeField] private Vector3 interactionRayPoint = default;
[SerializeField] private float interactionDistance = default;
[SerializeField] private LayerMask interactionLayer = default;
private Interactable_Dreamscape currentInteractable;
[Header("Movement Parameters")]
[SerializeField] private float walkSpeed = 3.0f;
[SerializeField] private float sprintSpeed = 6.0f;
[SerializeField] private float crouchSpeed = 1.5f;
[Header("Camera Parameters")]
[SerializeField, Range(1, 10)] private float lookSpeedX = 2.0f;
[SerializeField, Range(1, 10)] private float lookSpeedY = 2.0f;
[SerializeField, Range(1, 180)] private float lowerLookLimit = 80.0f;
[SerializeField, Range(1, 180)] private float upperLookLimit = 80.0f;
[Header("Jumping Parameters")]
[SerializeField] private float jumpForce = 8.0f;
[SerializeField] private float gravity = 30.0f;
[Header("Crouching Parameters")]
[SerializeField] private float crouchHeight = 0.5f;
[SerializeField] private float standinghHeight = 2f;
[SerializeField] private float timeToCrouch = 0.25f;
[SerializeField] private Vector3 crouchCenter = new Vector3(0, 0.5f, 0);
[SerializeField] private Vector3 standingCenter = new Vector3(0, 0, 0);
private bool isCrouching;
private bool duringCrouchAnim;
[Header("Headbob Parameters")]
[SerializeField] private float walkBobSpeed = 14.0f;
[SerializeField] private float walkBobAmount = 0.05f;
[SerializeField] private float sprintBobSpeed = 18.0f;
[SerializeField] private float sprintBobAmount = 0.11f;
[Header("Footstep Parameters")]
[SerializeField] private float baseStepSpeed = 0.5f;
[SerializeField] private float crouchStepMultiplier = 1.5f;
[SerializeField] private float sprintStepMultiplier = 0.6f;
[SerializeField] private AudioSource footstepAudioSource = default;
[SerializeField] private AudioClip[] woodClips = default;
[SerializeField] private AudioClip[] stoneClips = default;
[SerializeField] private AudioClip[] waterClips = default;
[SerializeField] private AudioClip[] grassClips = default;
private float footstepTimer = 0;
private float GetCurrentOffset => isCrouching ? baseStepSpeed * crouchStepMultiplier : isSprinting ? baseStepSpeed * sprintStepMultiplier : baseStepSpeed;
private float defaultYPos = 0;
private float timer;
private Camera playerCamera;
private CharacterController characterController;
private Vector3 moveDirection;
private Vector2 currentInput;
private float rotationX = 0;
void Awake()
{
playerCamera = GetComponentInChildren<Camera>();
characterController = GetComponent<CharacterController>();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
defaultYPos = playerCamera.transform.localPosition.y;
}
private void Start()
{
if (instance != null)
{
Destroy(gameObject);
}
else
{
instance = this;
}
DontDestroyOnLoad(gameObject);
}
// Update is called once per frame
void Update()
{
if (CanMove)
{
HandleMovementInput();
HandleMouseLook();
if (canJump)
HandleJump();
if (canCrouch)
HandleCrouch();
if (canHeadBob)
{
HandleHeadBob();
}
if (canInteract)
{
HandleInteractionCheck();
HandleInteractionInput();
}
if (useFootsteps)
{
HandleFootsteps();
}
ApplyFinalMovements();
}
}
private void HandleMovementInput()
{
currentInput = new Vector2((isCrouching ? crouchSpeed : isSprinting ? sprintSpeed : walkSpeed) * Input.GetAxis("Vertical"), (isCrouching ? crouchSpeed : isSprinting ? sprintSpeed : walkSpeed) * Input.GetAxis("Horizontal"));
float moveDirectionY = moveDirection.y;
moveDirection = (transform.TransformDirection(Vector3.forward) * currentInput.x) + (transform.TransformDirection(Vector3.right) * currentInput.y);
moveDirection.y = moveDirectionY;
}
private void HandleHeadBob()
{
if (!characterController.isGrounded) return;
if (Mathf.Abs(moveDirection.x) > 0.1f || Mathf.Abs(moveDirection.z) > 0.1f)
{
timer += Time.deltaTime * (isSprinting ? sprintBobSpeed : walkBobSpeed);
playerCamera.transform.localPosition = new Vector3(
playerCamera.transform.localPosition.x,
defaultYPos + Mathf.Sin(timer) * (isSprinting ? sprintBobAmount : walkBobAmount),
playerCamera.transform.localPosition.z);
}
}
private void HandleMouseLook()
{
rotationX -= Input.GetAxis("Mouse Y") * lookSpeedY;
rotationX = Mathf.Clamp(rotationX, -upperLookLimit, lowerLookLimit);
playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeedX, 0);
}
private void HandleJump()
{
if (ShouldJump)
moveDirection.y = jumpForce;
}
private void HandleCrouch()
{
if (ShouldCrouch)
StartCoroutine(CrouchStand());
}
private void ApplyFinalMovements()
{
if (!characterController.isGrounded)
moveDirection.y -= gravity * Time.deltaTime;
characterController.Move(moveDirection * Time.deltaTime);
}
private IEnumerator CrouchStand()
{
if (isCrouching && Physics.Raycast(playerCamera.transform.position, Vector3.up, 1f))
yield break;
duringCrouchAnim = true;
float timeElapsed = 0;
float targetHeight = isCrouching ? standinghHeight : crouchHeight;
float currentHeight = characterController.height;
Vector3 targetCenter = isCrouching ? standingCenter : crouchCenter;
Vector3 currentCenter = characterController.center;
while (timeElapsed < timeToCrouch)
{
characterController.height = Mathf.Lerp(currentHeight, targetHeight, timeElapsed / timeToCrouch);
characterController.center = Vector3.Lerp(currentCenter, targetCenter, timeElapsed / timeToCrouch);
timeElapsed += Time.deltaTime;
yield return null;
}
characterController.height = targetHeight;
characterController.center = targetCenter;
isCrouching = !isCrouching;
duringCrouchAnim = false;
}
private void HandleInteractionCheck()
{
if (Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance))
{
if(hit.collider.gameObject.layer == 7 && (currentInteractable == null || hit.collider.gameObject.GetInstanceID() != currentInteractable.gameObject.GetInstanceID()))
{
hit.collider.TryGetComponent(out currentInteractable);
if (currentInteractable)
currentInteractable.OnFocus();
}
}
else if (currentInteractable)
{
currentInteractable.OnLoseFocus();
currentInteractable = null;
}
}
private void HandleFootsteps()
{
if (!characterController.isGrounded) return;
if (currentInput == Vector2.zero) return;
footstepTimer -= Time.deltaTime;
if(footstepTimer <= 0)
{
if(Physics.Raycast(playerCamera.transform.position,Vector3.down, out RaycastHit hit, 2))
{
switch (hit.collider.tag)
{
case "Footsteps/Grass":
footstepAudioSource.PlayOneShot(grassClips[Random.Range(0, grassClips.Length - 1)]);
break;
case "Footsteps/Stone":
footstepAudioSource.PlayOneShot(stoneClips[Random.Range(0, stoneClips.Length - 1)]);
break;
case "Footsteps/Water":
footstepAudioSource.PlayOneShot(waterClips[Random.Range(0, waterClips.Length - 1)]);
break;
case "Footsteps/Wood":
footstepAudioSource.PlayOneShot(woodClips[Random.Range(0, woodClips.Length - 1)]);
break;
default:
footstepAudioSource.PlayOneShot(grassClips[Random.Range(0, grassClips.Length - 1)]);
break;
}
}
footstepTimer = GetCurrentOffset;
}
}
private void HandleInteractionInput()
{
if(Input.GetKeyDown(interactKey) && currentInteractable !=null && Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint),out RaycastHit hit, interactionDistance, interactionLayer))
{
currentInteractable.OnInteract();
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7910ea665f4b8bd4fbb6b8acfd3aebee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -14,8 +14,8 @@ namespace Polyart
{ {
if (PlayerPrefs.GetString("LastExitName") == lastExitName) if (PlayerPrefs.GetString("LastExitName") == lastExitName)
{ {
FirstPersonController_Polyart.instance.transform.position = transform.position; FirstPersonController.instance.transform.position = transform.position;
FirstPersonController_Polyart.instance.transform.eulerAngles = transform.eulerAngles; FirstPersonController.instance.transform.eulerAngles = transform.eulerAngles;
} }
} }

View File

@ -0,0 +1,216 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &7820060046865609844
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3489658851855711369}
- component: {fileID: 4830338463085844156}
- component: {fileID: 3711253093112916875}
- component: {fileID: 7774603027771940149}
- component: {fileID: 2816793236514826524}
- component: {fileID: 9190236701811369466}
m_Layer: 0
m_Name: PF_FreezeShard
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3489658851855711369
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7820060046865609844}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 122.128, y: 27.12, z: 345.44415}
m_LocalScale: {x: 0.83, y: 0.83, z: 0.83}
m_ConstrainProportionsScale: 1
m_Children:
- {fileID: 8387336634969776466}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &4830338463085844156
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7820060046865609844}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &3711253093112916875
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7820060046865609844}
m_Enabled: 0
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!135 &7774603027771940149
SphereCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7820060046865609844}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 1
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &2816793236514826524
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7820060046865609844}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3f8a87ffd94add94f81964c4de32beb2, type: 3}
m_Name:
m_EditorClassIdentifier:
damage: 0
freezeDuration: 0
ownerRoot: {fileID: 0}
armTime: 0.05
--- !u!54 &9190236701811369466
Rigidbody:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7820060046865609844}
serializedVersion: 4
m_Mass: 1
m_Drag: 0
m_AngularDrag: 0.05
m_CenterOfMass: {x: 0, y: 0, z: 0}
m_InertiaTensor: {x: 1, y: 1, z: 1}
m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_ImplicitCom: 1
m_ImplicitTensor: 1
m_UseGravity: 1
m_IsKinematic: 0
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!1001 &8387336634969417538
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 3489658851855711369}
m_Modifications:
- target: {fileID: 160792, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_Name
value: FrostMissile
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalRotation.w
value: 0.7071068
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalRotation.x
value: -0.7071068
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: -90
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: e532199d564214cd3afa871f43bd7cad, type: 3}
--- !u!4 &8387336634969776466 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 427536, guid: e532199d564214cd3afa871f43bd7cad,
type: 3}
m_PrefabInstance: {fileID: 8387336634969417538}
m_PrefabAsset: {fileID: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f9ff593927af6f54caa58e3cddae7410
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,167 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4006626876238256025
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7154477416992791333}
- component: {fileID: 7329990850358559462}
- component: {fileID: 568257675080800626}
- component: {fileID: 8060340817706815787}
- component: {fileID: 3951388154437428790}
- component: {fileID: 6743207068330466250}
- component: {fileID: 385312391933029727}
m_Layer: 0
m_Name: Enemy
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7154477416992791333
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 123.2, y: 26.79, z: 341.72}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &7329990850358559462
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &568257675080800626
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!136 &8060340817706815787
CapsuleCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 2
m_Radius: 0.5
m_Height: 2
m_Direction: 1
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &3951388154437428790
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7318ee1be010c1e43b9f45dbbe3a8d9d, type: 3}
m_Name:
m_EditorClassIdentifier:
maxHealth: 100
health: 100
enableRegen: 1
regenPerSecond: 1.5
regenDelayAfterDamage: 4
healthFillImage: {fileID: 0}
--- !u!195 &6743207068330466250
NavMeshAgent:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
m_Enabled: 1
m_AgentTypeID: 0
m_Radius: 0.5
m_Speed: 3.5
m_Acceleration: 8
avoidancePriority: 50
m_AngularSpeed: 120
m_StoppingDistance: 0
m_AutoTraverseOffMeshLink: 1
m_AutoBraking: 1
m_AutoRepath: 1
m_Height: 2
m_BaseOffset: 1
m_WalkableMask: 4294967295
m_ObstacleAvoidanceType: 4
--- !u!114 &385312391933029727
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4006626876238256025}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9de313fb3f367d04bbd130657183cdc8, type: 3}
m_Name:
m_EditorClassIdentifier:
config: {fileID: 11400000, guid: b1e6cf81537e753408031314323a53dc, type: 2}
target: {fileID: 0}
playerTag: Player

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a205c5f30032031428dae83c4a2f2af8
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,26 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 49bbd40b4b6c27046ad28ab6eb3de43e, type: 3}
m_Name: Freeze Shard Ability
m_EditorClassIdentifier:
displayName: Freeze Shard
icon: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0}
manaCost: 10
cooldown: 2
description:
projectilePrefab: {fileID: 7820060046865609844, guid: f9ff593927af6f54caa58e3cddae7410,
type: 3}
speed: 20
damage: 0
freezeDuration: 3
lifeTime: 4
spawnOffset: 0.5

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 036f9184f5c4730488f8cf0f55598b5d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,26 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e68b29079a00795429d5fe24103d9e4a, type: 3}
m_Name: MeleeEnemy
m_EditorClassIdentifier:
aggroRange: 15
loseAggroRange: 20
moveSpeed: 3.5
angularSpeed: 360
accel: 12
stoppingDistance: 1.2
attackRange: 1.6
attackDamage: 10
attackCooldown: 1.25
playerMask:
serializedVersion: 2
m_Bits: 4294967295

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b1e6cf81537e753408031314323a53dc
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -33,6 +33,8 @@ public class FreezableNavAgent : MonoBehaviour, IFreezable
_origAngSpeed = _agent.angularSpeed; _origAngSpeed = _agent.angularSpeed;
} }
public bool isFrozen { get; set; }
public void Freeze(float duration) public void Freeze(float duration)
{ {
// If already frozen, refresh duration // If already frozen, refresh duration

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 002414307a4f0bb44972aa4581f8ac6f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,180 @@
// EnemyBase.cs
using System.Collections;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(HealthManager))]
public abstract class EnemyBase : MonoBehaviour , IFreezable
{
public EnemyConfig config;
[Header("Targeting")]
public Transform target; // assign player at runtime or via tag lookup
public string playerTag = "Player"; // optional: auto-find
protected NavMeshAgent agent;
protected HealthManager health;
protected float lastAttackTime = -999f;
protected bool hasAggro;
public bool isFrozen { get; set; }
Coroutine _freezeCo;
float _origSpeed, _origAccel, _origAngSpeed;
protected virtual void Awake()
{
agent = GetComponent<NavMeshAgent>();
health = GetComponent<HealthManager>();
}
protected virtual void Start()
{
if (!target && !string.IsNullOrEmpty(playerTag))
{
var go = GameObject.FindGameObjectWithTag(playerTag);
if (go) target = go.transform;
}
ApplyConfig();
_origSpeed = agent.speed;
_origAccel = agent.acceleration;
_origAngSpeed = agent.angularSpeed;
}
protected virtual void Update()
{
if (!target || health.IsDead()) { Idle(); return; }
float dist = Vector3.Distance(transform.position, target.position);
if (!hasAggro)
{
if (dist <= config.aggroRange) hasAggro = true;
else { Idle(); return; }
}
else // has aggro
{
if (dist >= config.loseAggroRange)
{
hasAggro = false;
Idle();
return;
}
}
// move / attack
if (dist > config.attackRange)
{
Chase();
}
else
{
FaceTarget();
TryAttack();
}
}
protected virtual void Idle()
{
if (agent && agent.enabled)
{
agent.isStopped = true;
agent.ResetPath();
}
}
protected virtual void Chase()
{
if (!agent || !agent.enabled) return;
agent.isStopped = false;
agent.stoppingDistance = config.stoppingDistance;
agent.SetDestination(target.position);
}
protected void FaceTarget()
{
Vector3 to = target.position - transform.position;
to.y = 0f;
if (to.sqrMagnitude > 0.001f)
{
var look = Quaternion.LookRotation(to);
transform.rotation = Quaternion.RotateTowards(transform.rotation, look, config.angularSpeed * Time.deltaTime);
}
}
protected void ApplyConfig()
{
if (!agent || config == null) return;
agent.speed = config.moveSpeed;
agent.angularSpeed = config.angularSpeed;
agent.acceleration = config.accel;
agent.stoppingDistance = config.stoppingDistance;
}
// ====== Attacking (implemented in child classes) ======
protected abstract void TryAttack();
// ====== IDamageable (forward to HealthManager) ======
public void ApplyDamage(float amount) => health.TakeDamage(amount);
public bool IsDead() => health.IsDead();
// Handy debug
[ContextMenu("Debug/Take 10")]
void DebugHit() => ApplyDamage(10);
public void Freeze(float duration)
{
if (_freezeCo != null) StopCoroutine(_freezeCo);
_freezeCo = StartCoroutine(FreezeRoutine(duration));
}
IEnumerator FreezeRoutine(float duration)
{
// Enter freeze
if (!isFrozen) EnterFreeze();
// Wait for duration
float t = duration;
while (t > 0f)
{
t -= Time.deltaTime;
yield return null;
}
// Exit
ExitFreeze();
_freezeCo = null;
}
void EnterFreeze()
{
isFrozen = true;
// Stop movement immediately
if (agent)
{
agent.isStopped = true; // halts pathfinding updates
agent.ResetPath(); // clear current path
agent.velocity = Vector3.zero;
// Optional: zero out movement-related params to avoid jitter
agent.speed = 0f;
agent.acceleration = 0f;
agent.angularSpeed = 0f;
}
}
void ExitFreeze()
{
isFrozen = false;
if (agent)
{
// Restore movement settings
agent.speed = _origSpeed;
agent.acceleration = _origAccel;
agent.angularSpeed = _origAngSpeed;
agent.isStopped = false;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f6a7838a46759ed4a837fb6e77deef18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
// EnemyConfig.cs
using UnityEngine;
[CreateAssetMenu(menuName = "Enemies/Enemy Config")]
public class EnemyConfig : ScriptableObject
{
[Header("Sensing")]
public float aggroRange = 15f;
public float loseAggroRange = 20f;
[Header("Movement")]
public float moveSpeed = 3.5f;
public float angularSpeed = 360f;
public float accel = 12f;
public float stoppingDistance = 1.2f;
[Header("Combat")]
public float attackRange = 1.6f;
public float attackDamage = 10f;
public float attackCooldown = 1.25f;
[Header("Misc")]
public LayerMask playerMask = ~0; // or set a "Player" layer
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e68b29079a00795429d5fe24103d9e4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
// MeleeEnemy.cs
using UnityEngine;
public class MeleeEnemy : EnemyBase
{
protected override void TryAttack()
{
if (Time.time - lastAttackTime < config.attackCooldown) return;
// still in range?
if (Vector3.Distance(transform.position, target.position) > config.attackRange) return;
// perform attack
lastAttackTime = Time.time;
// Damage the target if its damageable
if (target.TryGetComponent<IDamageable>(out var dmg))
{
dmg.ApplyDamage(config.attackDamage);
}
// TODO: play swing anim / SFX here
// e.g., GetComponent<Animator>()?.SetTrigger("attack");
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9de313fb3f367d04bbd130657183cdc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
public interface IFreezable public interface IFreezable
{ {
public bool isFrozen { get; set;}
void Freeze(float duration); void Freeze(float duration);
} }

View File

@ -72,7 +72,7 @@ public class HealthManager : MonoBehaviour, IDamageable
var cc = GetComponent<CharacterController>(); var cc = GetComponent<CharacterController>();
if (cc) cc.enabled = false; if (cc) cc.enabled = false;
var fps = GetComponent<FirstPersonController_Polyart>(); var fps = GetComponent<FirstPersonController>();
if (fps) fps.enabled = false; if (fps) fps.enabled = false;
} }

View File

@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"com.unity.ai.navigation": "1.1.7",
"com.unity.collab-proxy": "2.8.2", "com.unity.collab-proxy": "2.8.2",
"com.unity.ide.rider": "3.0.31", "com.unity.ide.rider": "3.0.31",
"com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.visualstudio": "2.0.22",

View File

@ -1,5 +1,14 @@
{ {
"dependencies": { "dependencies": {
"com.unity.ai.navigation": {
"version": "1.1.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.ai": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.burst": { "com.unity.burst": {
"version": "1.8.18", "version": "1.8.18",
"depth": 1, "depth": 1,

View File

@ -69,9 +69,9 @@ NavMeshProjectSettings:
cost: 1 cost: 1
- name: - name:
cost: 1 cost: 1
m_LastAgentTypeID: -887442657 m_LastAgentTypeID: -1372625422
m_Settings: m_Settings:
- serializedVersion: 2 - serializedVersion: 3
agentTypeID: 0 agentTypeID: 0
agentRadius: 0.5 agentRadius: 0.5
agentHeight: 2 agentHeight: 2
@ -84,7 +84,9 @@ NavMeshProjectSettings:
cellSize: 0.16666667 cellSize: 0.16666667
manualTileSize: 0 manualTileSize: 0
tileSize: 256 tileSize: 256
accuratePlacement: 0 buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug: debug:
m_Flags: 0 m_Flags: 0
m_SettingNames: m_SettingNames:

View File

@ -11,7 +11,7 @@ TagManager:
- -
- Water - Water
- UI - UI
- - WalkableStreet
- -
- -
- -