diff --git a/MrBigsock/Assets/Code/Slime.meta b/MrBigsock/Assets/Code/Slime.meta new file mode 100644 index 0000000000000000000000000000000000000000..73b4fb95597ed1b95b51082395d2f04a6d5ab181 --- /dev/null +++ b/MrBigsock/Assets/Code/Slime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9eccdf20947a9554da1465097eadf921 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MrBigsock/Assets/Code/Slime/SlimeController.cs b/MrBigsock/Assets/Code/Slime/SlimeController.cs new file mode 100644 index 0000000000000000000000000000000000000000..24a65bbad9f5fc1cf2becfe33b50ce74fd17047c --- /dev/null +++ b/MrBigsock/Assets/Code/Slime/SlimeController.cs @@ -0,0 +1,235 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System.Linq; +using System; + + +namespace BigSock { + + public partial class SlimeController : Character { + public float collisionOffset = 0.05f; + public ContactFilter2D movementFilter; + List<RaycastHit2D> castCollisions = new List<RaycastHit2D>(); + + private Transform target; + Animator m_Animator; + private float distance; + + private float canAttack; + + private EmptyCollider followCollider; + private EmptyCollider attackCollider; + + private bool isInMelee = false; + + + Rigidbody2D rb; + + // private Collider2D_Proxy secondCollider; + + /* + The state the slime is in. + */ + public SlimeState State { get; protected set; } = SlimeState.Idle; + + + /* + The location of the target when charging started. + */ + public Vector3 TargetLocation { get; protected set; } + + /* + The next time the slime can change its state. + */ + public DateTime NextTimeStateCanChange { get; private set; } = DateTime.Now; + + /* + Minimum time the slime should idle before it can charge. + */ + protected static readonly TimeSpan IDLE_WAIT_TIME = new TimeSpan(0, 0, 0, 1, 0); + /* + Minimum time the slime should charge before it can leap. + */ + protected static readonly TimeSpan CHARGE_WAIT_TIME = new TimeSpan(0, 0, 0, 2, 0); + /* + Maximum time the slime should leap before it can idle. + */ + protected static readonly TimeSpan LEAP_WAIT_TIME = new TimeSpan(0, 0, 0, 4, 0); + + /* + The force the slime leaps at. + */ + public double LeapForce => MovementSpeed * 4; + + + void Start() { + rb = GetComponent<Rigidbody2D>(); + + m_Animator = gameObject.GetComponent<Animator>(); + + followCollider = transform.Find("followCollider").GetComponent<EmptyCollider>(); + followCollider.OnColliderEnter2D_Action += Move_OnColliderEnter2D; + followCollider.OnColliderStay2D_Action += Move_OnColliderStay2D; + followCollider.OnColliderExit2D_Action += Move_OnColliderExit2D; + + attackCollider = transform.Find("MeleeCollider").GetComponent<EmptyCollider>(); + attackCollider.OnColliderEnter2D_Action += Attack_OnColliderEnter2D; + attackCollider.OnColliderStay2D_Action += Attack_OnColliderStay2D; + attackCollider.OnColliderExit2D_Action += Attack_OnColliderExit2D; + } + + + + + + + + private void RotateAnimation(Vector2 direction) + { + if (direction.x > 0.01f){ + gameObject.GetComponent<SpriteRenderer>().flipX = false; + } + else if (direction.x < -0.01f){ + gameObject.GetComponent<SpriteRenderer>().flipX = true; + } + + } + + private void Update() { + if(State == SlimeState.Idle) { + // If it has a target and has idled long enough. + if(target != null && DateTime.Now >= NextTimeStateCanChange) { + // Store target location. + TargetLocation = target.position; + + // Update the state. + State = SlimeState.Charging; + NextTimeStateCanChange = DateTime.Now + CHARGE_WAIT_TIME; + m_Animator.SetTrigger("walk"); + } + } + + else if(State == SlimeState.Charging) { + // If it has charged long enough. + if(DateTime.Now >= NextTimeStateCanChange) { + // Set momentum + var pos = TargetLocation;//target.position; + var temp = (pos - rb.transform.position); + temp.z = 0; + var direction = temp.normalized; + rb.AddForce((float) LeapForce * direction, ForceMode2D.Impulse); + + // Update the state. + State = SlimeState.Leaping; + NextTimeStateCanChange = DateTime.Now + LEAP_WAIT_TIME; + } + } + + else if(State == SlimeState.Leaping) { + // If it has charged long enough. + if(DateTime.Now >= NextTimeStateCanChange || rb.velocity == Vector2.zero) { + // Update the state. + State = SlimeState.Idle; + NextTimeStateCanChange = DateTime.Now + IDLE_WAIT_TIME; + m_Animator.SetTrigger("idle"); + + } + } + + } + + private bool TryMove(Vector2 direction) { + + if(direction != Vector2.zero) { + + // Check for potential collisions + int count = rb.Cast( + direction, // X and Y values between -1 and 1 that represent the direction from the body to look for collisions + movementFilter, // The settings that determine where a collision can occur on such as layers to collide with + castCollisions, // List of collisions to store the found collisions into after the Cast is finished + (float) MovementSpeed * Time.fixedDeltaTime + collisionOffset); // The amount to cast equal to the movement plus an offset + //Debug.Log($"cast {string.Join(", ", castCollisions.Select(x => $"{x.collider.isTrigger}"))}"); + //Debug.Log($"rb.position : {rb.position}"); + //Debug.Log($"target.position : {target.position}"); + //Debug.Log($"direction : {direction}"); + if(count == 0){ + rb.MovePosition(rb.position + direction * (float) MovementSpeed * Time.fixedDeltaTime); + //print($"rb.position {rb.position}"); + //print($"direction {direction}"); + RotateAnimation(direction); + + return true; + } else { + return false; + } + } else { + // Can't move if there's no direction to move in + return false; + } + + } + } + + + /* + Attack + */ + public partial class SlimeController { + + private void Attack_OnColliderEnter2D(Collider2D other){ + if (other.gameObject.tag == "Player") + isInMelee = true; + } + + + private void Attack_OnColliderStay2D(Collider2D other){ + var player = other.gameObject.GetComponent<PlayerController>(); + if (player != null){ + if(player.TakeDamage(Damage)) { + //knockback ? + //animer nå ? + + } + } + } + + private void Attack_OnColliderExit2D(Collider2D other){ + if (other.gameObject.tag == "Player") + isInMelee = false; + } + + } + + /* + Movement + */ + public partial class SlimeController { + + private void Move_OnColliderEnter2D(Collider2D other) { + if (other.gameObject.tag == "Player") { + //m_Animator.SetTrigger("walk"); + target = other.transform; + } + } + + private void Move_OnColliderStay2D(Collider2D other) { + if (other.gameObject.tag == "Player") { } + } + + private void Move_OnColliderExit2D(Collider2D other) { + if (other.gameObject.tag == "Player") { + //m_Animator.SetTrigger("idle"); + target = null; + } + } + + } + + /* + The different states the slime can be in. + */ + public enum SlimeState { + Idle, Charging, Leaping + } +} diff --git a/MrBigsock/Assets/Code/Slime/SlimeController.cs.meta b/MrBigsock/Assets/Code/Slime/SlimeController.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..ee538aacbb0dfd7b074211879be133d19683c617 --- /dev/null +++ b/MrBigsock/Assets/Code/Slime/SlimeController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab60f8264e1adb04f9c19814ddca9ccc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MrBigsock/Assets/Prefabs/Enemy_Slime.prefab b/MrBigsock/Assets/Prefabs/Enemy_Slime.prefab new file mode 100644 index 0000000000000000000000000000000000000000..3a07d08adb0195c0e6e83852a29aa20b4c947d88 --- /dev/null +++ b/MrBigsock/Assets/Prefabs/Enemy_Slime.prefab @@ -0,0 +1,313 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2996495149472241661 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7097463258699610772} + - component: {fileID: 65690667081962088} + - component: {fileID: 8506405333948921944} + - component: {fileID: 5891912875293609069} + - component: {fileID: 2395291586284291126} + - component: {fileID: -2882901802891604921} + m_Layer: 0 + m_Name: Enemy_Slime + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7097463258699610772 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2996495149472241661} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2753253562357840752} + - {fileID: 1701851832504875480} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &65690667081962088 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2996495149472241661} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + 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: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 2 + m_Sprite: {fileID: 21300000, guid: dfb75b4c193e2994dabfcb50c3cf64e5, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 0.16, y: 0.2} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!50 &8506405333948921944 +Rigidbody2D: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2996495149472241661} + m_BodyType: 0 + m_Simulated: 1 + m_UseFullKinematicContacts: 1 + m_UseAutoMass: 1 + m_Mass: 0.6243647 + m_LinearDrag: 2.5 + m_AngularDrag: 0 + m_GravityScale: 0 + m_Material: {fileID: 0} + m_Interpolate: 0 + m_SleepingMode: 1 + m_CollisionDetection: 0 + m_Constraints: 4 +--- !u!95 &5891912875293609069 +Animator: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2996495149472241661} + m_Enabled: 1 + m_Avatar: {fileID: 0} + m_Controller: {fileID: 9100000, guid: 87d00f377b8992e4092c2ea820422659, type: 2} + m_CullingMode: 0 + m_UpdateMode: 0 + m_ApplyRootMotion: 0 + m_LinearVelocityBlending: 0 + m_StabilizeFeet: 0 + m_WarningMessage: + m_HasTransformHierarchy: 1 + m_AllowConstantClipSamplingOptimization: 1 + m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!61 &2395291586284291126 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2996495149472241661} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0.06446171, y: -0.1364619} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0.5, y: 0.5} + oldSize: {x: 1, y: 1.25} + newSize: {x: 0.16, y: 0.2} + adaptiveTilingThreshold: 0.5 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 0.6390133, y: 0.9770762} + m_EdgeRadius: 0 +--- !u!114 &-2882901802891604921 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2996495149472241661} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ab60f8264e1adb04f9c19814ddca9ccc, type: 3} + m_Name: + m_EditorClassIdentifier: + baseAttackSpeed: 1 + baseMovementSpeed: 2 + baseDamage: 1 + baseHP: 10 + baseMaxHP: 10 + collisionOffset: 0.05 + movementFilter: + useTriggers: 0 + useLayerMask: 1 + useDepth: 0 + useOutsideDepth: 0 + useNormalAngle: 0 + useOutsideNormalAngle: 0 + layerMask: + serializedVersion: 2 + m_Bits: 0 + minDepth: 0 + maxDepth: 0 + minNormalAngle: 0 + maxNormalAngle: 0 +--- !u!1 &7539630614846898202 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2753253562357840752} + - component: {fileID: 7566484513581878393} + - component: {fileID: 8365831662590702362} + m_Layer: 3 + m_Name: followCollider + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2753253562357840752 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7539630614846898202} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7097463258699610772} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!58 &7566484513581878393 +CircleCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7539630614846898202} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 1 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + serializedVersion: 2 + m_Radius: 8 +--- !u!114 &8365831662590702362 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7539630614846898202} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b1aeda8fe8f5c1f4fa7a8f47e2864211, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &8620845285361089561 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1701851832504875480} + - component: {fileID: 8983526051028480608} + - component: {fileID: 6373942986610437007} + m_Layer: 3 + m_Name: MeleeCollider + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1701851832504875480 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8620845285361089561} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.04, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7097463258699610772} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!58 &8983526051028480608 +CircleCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8620845285361089561} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 1 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + serializedVersion: 2 + m_Radius: 0.7 +--- !u!114 &6373942986610437007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8620845285361089561} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b1aeda8fe8f5c1f4fa7a8f47e2864211, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/MrBigsock/Assets/Prefabs/Enemy_Slime.prefab.meta b/MrBigsock/Assets/Prefabs/Enemy_Slime.prefab.meta new file mode 100644 index 0000000000000000000000000000000000000000..07870986c764d5401f7cb787560b0e641d147efc --- /dev/null +++ b/MrBigsock/Assets/Prefabs/Enemy_Slime.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0c78162db0e5ea443a58406283e89a8e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MrBigsock/ProjectSettings/Physics2DSettings.asset b/MrBigsock/ProjectSettings/Physics2DSettings.asset index 6cfcddaacd6468d283a2d3f7017eaca4762ca6a7..ff6f57d502c6c6c0942d69e0183ca998677b2d6e 100644 --- a/MrBigsock/ProjectSettings/Physics2DSettings.asset +++ b/MrBigsock/ProjectSettings/Physics2DSettings.asset @@ -53,4 +53,4 @@ Physics2DSettings: m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} - m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffdff9ffffffffffffffffffffffffffffdffbffffdff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/MrBigsock/ProjectSettings/TagManager.asset b/MrBigsock/ProjectSettings/TagManager.asset index 1c92a7840ec11895c76785f65d949a3d20d53355..9a93f78ef7741fff08100f45a720617a8b27c9ad 100644 --- a/MrBigsock/ProjectSettings/TagManager.asset +++ b/MrBigsock/ProjectSettings/TagManager.asset @@ -14,8 +14,8 @@ TagManager: - - - - - - - + - Player + - PlayerProjectile - - -