diff --git a/BlueWater/Assets/01.Scenes/02.Ocean.unity b/BlueWater/Assets/01.Scenes/02.Ocean.unity index 595c18d67..29ad17a0f 100644 --- a/BlueWater/Assets/01.Scenes/02.Ocean.unity +++ b/BlueWater/Assets/01.Scenes/02.Ocean.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 55264370} - m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_IndirectSpecularColor: {r: 0.11325848, g: 0.48708495, b: 0.73601764, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &4 LightmapSettings: @@ -93,7 +93,7 @@ LightmapSettings: m_ExportTrainingData: 0 m_TrainingDataDestination: TrainingData m_LightProbeSampleCountMultiplier: 4 - m_LightingDataAsset: {fileID: 112000000, guid: 5736bec67810b487292714d0ee92c603, + m_LightingDataAsset: {fileID: 112000000, guid: 90581f249edafa242846d362aac473f4, type: 2} m_LightingSettings: {fileID: 4890085278179872738, guid: eb906a94997a744cd99b204013bbc54c, type: 2} @@ -11027,7 +11027,7 @@ SpriteRenderer: m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingLayer: 0 - m_SortingOrder: 0 + m_SortingOrder: 2 m_Sprite: {fileID: 21300000, guid: 76cb51117ead0a94ba2c9b11409a3c1b, type: 3} m_Color: {r: 1, g: 0, b: 0, a: 1} m_FlipX: 0 @@ -11179,7 +11179,7 @@ GameObject: m_Component: - component: {fileID: 1286537730} m_Layer: 7 - m_Name: FirePos + m_Name: LaunchPosition m_TagString: Untagged m_Icon: {fileID: -5442936267250999957, guid: 0000000000000000d000000000000000, type: 0} m_NavMeshLayer: 0 @@ -11193,13 +11193,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1286537729} serializedVersion: 2 - m_LocalRotation: {x: 0.2588191, y: 0, z: 0, w: 0.9659258} - m_LocalPosition: {x: 0, y: 1.012, z: 1.322} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.389, z: 0.929} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4529632010256581} - m_LocalEulerAnglesHint: {x: 30, y: 0, z: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &1302515238 stripped Transform: m_CorrespondingSourceObject: {fileID: 412716, guid: e1c4cc5b9a7d0d7479734ea4167d417e, @@ -12785,8 +12785,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1485085414} serializedVersion: 2 - m_LocalRotation: {x: 0.3802585, y: 0.6187169, z: -0.46294743, w: 0.50820535} - m_LocalPosition: {x: -0.0014457703, y: 0, z: -0.0072784424} + m_LocalRotation: {x: 0.38026118, y: 0.61871386, z: -0.4629451, w: 0.508209} + m_LocalPosition: {x: -0.0015602112, y: 0, z: -0.007865906} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -16357,12 +16357,12 @@ GameObject: - component: {fileID: 1913692421} - component: {fileID: 1913692422} m_Layer: 0 - m_Name: Line + m_Name: CannonLineRenderer m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!4 &1913692421 Transform: m_ObjectHideFlags: 0 @@ -16371,7 +16371,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1913692420} serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalRotation: {x: 0.16504757, y: -0, z: -0, w: 0.9862857} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -16401,7 +16401,7 @@ LineRenderer: m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: - - {fileID: 0} + - {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 @@ -16419,15 +16419,15 @@ LineRenderer: m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 + m_SortingLayerID: -1197429611 + m_SortingLayer: 2 m_SortingOrder: 0 m_Positions: - {x: 0, y: 0, z: 0} - {x: 0, y: 0, z: 1} m_Parameters: serializedVersion: 3 - widthMultiplier: 1 + widthMultiplier: 0.1 widthCurve: serializedVersion: 2 m_Curve: @@ -16445,8 +16445,8 @@ LineRenderer: m_RotationOrder: 4 colorGradient: serializedVersion: 2 - key0: {r: 1, g: 1, b: 1, a: 1} - key1: {r: 1, g: 1, b: 1, a: 1} + key0: {r: 1, g: 0.5019608, b: 0, a: 1} + key1: {r: 1, g: 0, b: 0, a: 1} key2: {r: 0, g: 0, b: 0, a: 0} key3: {r: 0, g: 0, b: 0, a: 0} key4: {r: 0, g: 0, b: 0, a: 0} @@ -16470,7 +16470,7 @@ LineRenderer: atime6: 0 atime7: 0 m_Mode: 0 - m_ColorSpace: -1 + m_ColorSpace: 0 m_NumColorKeys: 2 m_NumAlphaKeys: 2 numCornerVertices: 0 @@ -16483,7 +16483,7 @@ LineRenderer: m_MaskInteraction: 0 m_UseWorldSpace: 1 m_Loop: 0 - m_ApplyActiveColorSpace: 1 + m_ApplyActiveColorSpace: 0 --- !u!1 &1916408931 GameObject: m_ObjectHideFlags: 0 @@ -18220,13 +18220,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1595413212644777} serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalRotation: {x: -0.16504757, y: 0, z: 0, w: 0.9862857} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4529632010256581} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_LocalEulerAnglesHint: {x: -19, y: 0, z: 0} --- !u!4 &4529632010256581 Transform: m_ObjectHideFlags: 0 @@ -18235,8 +18235,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1644207063785795} serializedVersion: 2 - m_LocalRotation: {x: -0.08715578, y: 0, z: 0, w: 0.9961947} - m_LocalPosition: {x: 0, y: 5.262, z: 3.23} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 5.315, z: 3.352} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -18244,7 +18244,7 @@ Transform: - {fileID: 1286537730} - {fileID: 1913692421} m_Father: {fileID: 975912082} - m_LocalEulerAnglesHint: {x: -10, y: 0, z: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &4529632010256582 MonoBehaviour: m_ObjectHideFlags: 0 @@ -18257,34 +18257,48 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3e8c36fe9172849798f9c4fd87b77ec7, type: 3} m_Name: m_EditorClassIdentifier: - autoInit: 1 + autoInit: 0 playerInput: {fileID: 975912080} - projectileObj: {fileID: 128572, guid: 8d387b0f65dfa4cdc965c4b56216e120, type: 3} - firePos: {fileID: 1286537730} - directionIndicator: {fileID: 1199960033} - cannonProcessBar: + projectileObject: {fileID: 128572, guid: 8d387b0f65dfa4cdc965c4b56216e120, type: 3} + visualLook: {fileID: 4143712617986135} + launchTransform: {fileID: 1286537730} + predictedLine: {fileID: 1913692422} + hitMarker: {fileID: 5951017876843886146, guid: 0eef5d11a5bdac248b2d16d733fd357c, + type: 3} + directionIndicator: {fileID: 0} + launchProcessBar: k__BackingField: {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: {fileID: 0} k__BackingField: 0 k__BackingField: 0 - cannonCooldown: 1 - chargingSpeed: 1 - fireAngle: 0.2 - launchSpeed: 75 - launchAngle: 30 + instantiateObjects: {fileID: 1700262530} + gaugeChargingTime: 1 + launchCooldown: 1 + distanceCoefficient: 40 + launchType: 0 + launchSpeed: 30 + launchAngle: 10 + isUsingPredictLine: 1 + lineMaxPoint: 100 + lineInterval: 0.025 randomCatch: {x: 1, y: 4} + mouseRayDistance: 500 + rayDistance: 10 + hitLayer: + serializedVersion: 2 + m_Bits: 2237976 waterLayer: serializedVersion: 2 m_Bits: 16 - targetLayer: + boidsLayer: serializedVersion: 2 m_Bits: 32768 cameraShakePower: 2 cameraShakeDuration: 0.3 - isFireMode: 0 - chargingCannon: 0 + isLaunchMode: 0 + isCharging: 0 isReloading: 0 chargingGauge: 0 previousGauge: 0 diff --git a/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-0.png b/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-0.png index 903134145..7eee631c0 100644 Binary files a/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-0.png and b/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-0.png differ diff --git a/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-1.exr b/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-1.exr index 0d310ee3e..1ea1168df 100644 Binary files a/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-1.exr and b/BlueWater/Assets/01.Scenes/02.Ocean/ReflectionProbe-1.exr differ diff --git a/BlueWater/Assets/02.Scripts/Player/Cannon.cs b/BlueWater/Assets/02.Scripts/Player/Cannon.cs index 22cd710ca..44b8e1eba 100644 --- a/BlueWater/Assets/02.Scripts/Player/Cannon.cs +++ b/BlueWater/Assets/02.Scripts/Player/Cannon.cs @@ -11,41 +11,98 @@ namespace BlueWaterProject { public class Cannon : MonoBehaviour { + /*********************************************************************** + * Definitions + ***********************************************************************/ + #region Definitions + + private enum LaunchType + { + NONE = -1, + FIXED_ANGLE, + FIXED_SPEED + } + + #endregion + /*********************************************************************** * Variables ***********************************************************************/ #region Variables + // 초기화 방식 [Title("초기화 방식")] [SerializeField] private bool autoInit = true; + // 컴포넌트 [Title("컴포넌트")] [SerializeField] private PlayerInput playerInput; - [SerializeField] private GameObject projectileObj; - [SerializeField] private Transform firePos; + [SerializeField] private GameObject projectileObject; + [SerializeField] private Transform visualLook; + [SerializeField] private Transform launchTransform; + [SerializeField] private LineRenderer predictedLine; + [SerializeField] private GameObject hitMarker; [SerializeField] private GameObject directionIndicator; - [SerializeField] private ProcessBar cannonProcessBar; + [SerializeField] private ProcessBar launchProcessBar; + [SerializeField] private Transform instantiateObjects; - [Title("대포 변수")] - [SerializeField] private float cannonCooldown = 1f; - [SerializeField] private float chargingSpeed = 1f; - [Range(0f, 0.5f)] - [SerializeField] private float fireAngle = 0.2f; - [SerializeField] private float launchSpeed = 75f; - [SerializeField] private float launchAngle = 30f; + // 게이지 옵션 + [Title("게이지 옵션")] + [Range(0.1f, 5f), Tooltip("게이지가 모두 차는데 걸리는 시간\n게이지는 0 ~ 1의 값을 가짐")] + [SerializeField] private float gaugeChargingTime = 1f; + + // 발사 옵션 + [Title("발사 옵션")] + [Range(0f, 3f), Tooltip("발사 재사용 시간")] + [SerializeField] private float launchCooldown = 1f; + + [Range(1f, 100f), Tooltip("발사될 거리 계수\nchargingGauge * 변수값")] + [SerializeField] private float distanceCoefficient = 40f; + + [Tooltip("발사 방식")] + [SerializeField] private LaunchType launchType = LaunchType.FIXED_ANGLE; + + [ShowIf("@launchType == LaunchType.FIXED_SPEED")] + [Range(0f, 100f), Tooltip("발사 속도")] + [SerializeField] private float launchSpeed = 20f; + + [ShowIf("@launchType == LaunchType.FIXED_ANGLE")] + [Range(0f, 60f), Tooltip("발사 각도")] + [SerializeField] private float launchAngle = 10f; + + [Title("발사 예측 옵션")] + [SerializeField] private bool isUsingPredictLine; + + [ShowIf("@isUsingPredictLine")] + [Range(1, 200), Tooltip("발사 예측선 갯수")] + [SerializeField] private int lineMaxPoint = 100; + + [ShowIf("@isUsingPredictLine")] + [Range(0.001f, 1f), Tooltip("발사 예측선 간격")] + [SerializeField] private float lineInterval = 0.025f; + + // 기타 옵션 + [Title("기타 옵션")] + [Tooltip("랜덤으로 잡힐 물고기 마릿수")] [SerializeField] private Vector2 randomCatch = new(1, 4); - [SerializeField] private LayerMask waterLayer; - [SerializeField] private LayerMask targetLayer; - [Title("캐논 발사 카메라 효과")] + [SerializeField] private float mouseRayDistance = 500f; + [SerializeField] private float rayDistance = 10f; + [SerializeField] private LayerMask hitLayer; + [SerializeField] private LayerMask waterLayer; + [SerializeField] private LayerMask boidsLayer; + + // 카메라 효과 옵션 + [Title("카메라 효과 옵션")] [SerializeField] private float cameraShakePower = 2f; [SerializeField] private float cameraShakeDuration = 0.3f; - [Title("실시간 상태")] + // 실시간 데이터 + [Title("실시간 데이터")] [DisableIf("@true")] - [SerializeField] private bool isFireMode; + [SerializeField] private bool isLaunchMode; [DisableIf("@true")] - [SerializeField] private bool chargingCannon; + [SerializeField] private bool isCharging; [DisableIf("@true")] [SerializeField] private bool isReloading; [DisableIf("@true")] @@ -54,7 +111,11 @@ namespace BlueWaterProject [SerializeField] private float previousGauge; private float cannonRadius; - private Collider[] hitColliders = new Collider[3]; + private Vector3 launchVelocity; + private Collider[] hitColliders; + private GameObject newHitMarker; + + private const int MAX_HIT_SIZE = 8; #endregion @@ -73,7 +134,11 @@ namespace BlueWaterProject private void Start() { - cannonProcessBar = UiManager.Inst.OceanUi.ProcessBar; + cannonRadius = projectileObject.GetComponent()?.radius ?? + projectileObject.GetComponent().colliderRadius; + + launchProcessBar = UiManager.Inst.OceanUi.ProcessBar; + hitColliders = new Collider[MAX_HIT_SIZE]; } private void OnEnable() @@ -106,15 +171,24 @@ namespace BlueWaterProject private void Init() { playerInput = GetComponentInParent(); - projectileObj = Utils.LoadFromFolder("Assets/05.Prefabs/Particles/GrenadeFire", "GrenadeFireOBJ", ".prefab"); - firePos = transform.Find("FirePos"); - directionIndicator = transform.parent.Find("DirectionIndicator").gameObject; - directionIndicator.SetActive(false); + projectileObject = Utils.LoadFromFolder("Assets/05.Prefabs/Particles/GrenadeFire", "GrenadeFireOBJ", ".prefab"); + visualLook = transform.Find("VisualLook"); + launchTransform = transform.Find("LaunchPosition"); + predictedLine = transform.Find("CannonLineRenderer").GetComponent(); + if (predictedLine) + { + predictedLine.gameObject.SetActive(false); + } + hitMarker = Utils.LoadFromFolder("Assets/05.Prefabs", "HitMarker", ".prefab"); + directionIndicator = transform.parent.Find("DirectionIndicator")?.gameObject; + if (directionIndicator) + { + directionIndicator.SetActive(false); + } + instantiateObjects = GameObject.Find("InstantiateObjects").transform; - cannonRadius = projectileObj.GetComponent()?.radius ?? - projectileObj.GetComponent().colliderRadius; waterLayer = LayerMask.GetMask("Water"); - targetLayer = LayerMask.GetMask("Boids"); + boidsLayer = LayerMask.GetMask("Boids"); } #endregion @@ -126,25 +200,28 @@ namespace BlueWaterProject private void ToggleCannon() { - isFireMode = !isFireMode; - directionIndicator.SetActive(isFireMode); - cannonProcessBar.SetActive(isFireMode); - - if (!isFireMode) + isLaunchMode = !isLaunchMode; + if (directionIndicator) { - chargingCannon = false; + directionIndicator.SetActive(isLaunchMode); + } + launchProcessBar.SetActive(isLaunchMode); + + if (!isLaunchMode) + { + isCharging = false; chargingGauge = 0f; previousGauge = chargingGauge; - cannonProcessBar.SetFillAmount(0f); - cannonProcessBar.SetRotateZ(previousGauge * -360f); - cannonProcessBar.SetRotateZ(0f); - cannonProcessBar.SetSliderValue(0f); + launchProcessBar.SetFillAmount(0f); + launchProcessBar.SetRotateZ(previousGauge * -360f); + launchProcessBar.SetRotateZ(0f); + launchProcessBar.SetSliderValue(0f); } } private void ChargeCannon() { - if (!isFireMode) return; + if (!isLaunchMode) return; if (isReloading) { @@ -152,25 +229,31 @@ namespace BlueWaterProject } else { - chargingCannon = true; + predictedLine.gameObject.SetActive(true); + if (hitMarker) + { + newHitMarker = Instantiate(hitMarker, Vector3.zero, hitMarker.transform.rotation, instantiateObjects); + newHitMarker.transform.localScale *= cannonRadius * 2f; + hitMarker.SetActive(true); + } + isCharging = true; chargingGauge = 0f; } } private void FireCannon() { - if (!isFireMode || !chargingCannon) return; + if (!isLaunchMode || !isCharging) return; - chargingCannon = false; - // previousGauge = 0f ~ 1f + isCharging = false; + predictedLine.gameObject.SetActive(false); previousGauge = chargingGauge; chargingGauge = 0f; - cannonProcessBar.SetFillAmount(0f); - cannonProcessBar.SetRotateZ(previousGauge * -360f); - Fire(previousGauge * 100); - isReloading = true; + launchProcessBar.SetFillAmount(0f); + launchProcessBar.SetRotateZ(previousGauge * -360f); + Launch(); - StartCoroutine(CannonCoolDown(cannonCooldown)); + StartCoroutine(LaunchCoolDown(launchCooldown)); } #endregion @@ -182,106 +265,210 @@ namespace BlueWaterProject private void HandleFireCannon() { - if (!isFireMode) return; + if (!isLaunchMode) return; var ray = CameraManager.Inst.MainCam.ScreenPointToRay(Input.mousePosition); - if (Physics.Raycast(ray, out var hit, Mathf.Infinity, waterLayer)) + if (Physics.Raycast(ray, out var hit, mouseRayDistance, waterLayer, QueryTriggerInteraction.Collide)) { - var directionToMouse = hit.point - directionIndicator.transform.position; + var directionToMouse = (hit.point - transform.position).normalized; directionToMouse.y = 0f; var lookRotation = Quaternion.LookRotation(directionToMouse); - var indicatorRotationDirection = Quaternion.Euler(0f, lookRotation.eulerAngles.y, 0f); + if (directionIndicator) + { + var indicatorRotationDirection = Quaternion.Euler(0f, lookRotation.eulerAngles.y, 0f); + directionIndicator.transform.rotation = indicatorRotationDirection; + } var cannonRotationDirection = Quaternion.Euler(transform.rotation.eulerAngles.x, lookRotation.eulerAngles.y, 0f); - directionIndicator.transform.rotation = indicatorRotationDirection; transform.rotation = cannonRotationDirection; } - if (!chargingCannon) return; + if (!isCharging) return; if (chargingGauge < 1f) { - chargingGauge += chargingSpeed * Time.deltaTime; + if (gaugeChargingTime == 0f) + { + gaugeChargingTime = 1f; + } + + chargingGauge += 1 / gaugeChargingTime * Time.deltaTime; chargingGauge = Mathf.Clamp(chargingGauge, 0f, 1f); } else { chargingGauge = 1f; } - cannonProcessBar.SetFillAmount(chargingGauge); + launchProcessBar.SetFillAmount(chargingGauge); - // if (!isFireMode) return; - // - // var ray = CameraManager.Inst.MainCam.ScreenPointToRay(Input.mousePosition); - // - // if (Physics.Raycast(ray, out var hit, Mathf.Infinity, waterLayer)) - // { - // var directionToMouse = hit.point - directionIndicator.transform.position; - // directionToMouse.y = 0f; - // - // var lookRotation = Quaternion.LookRotation(directionToMouse); - // var indicatorRotationDirection = Quaternion.Euler(0f, lookRotation.eulerAngles.y, 0f); - // var cannonRotationDirection = Quaternion.Euler(cannon.transform.rotation.eulerAngles.x, lookRotation.eulerAngles.y, 0f); - // directionIndicator.transform.rotation = indicatorRotationDirection; - // cannon.transform.rotation = cannonRotationDirection; - // } - // - // if (!chargingCannon) return; - // - // if (chargingGauge < 1f) - // { - // chargingGauge += chargingSpeed * Time.deltaTime; - // chargingGauge = Mathf.Clamp(chargingGauge, 0f, 1f); - // } - // else - // { - // chargingGauge = 1f; - // } - // UiManager.Inst.OceanUi.ProcessBar.SetFillAmount(chargingGauge); + CalculateLaunchTrajectory(); } - private IEnumerator CannonCoolDown(float waitTime) + private void CalculateLaunchTrajectory() + { + var startPosition = launchTransform.position; + var endPosition = CalculateEndPosition(); + + switch (launchType) + { + case LaunchType.NONE: + break; + case LaunchType.FIXED_ANGLE: + var currentEulerX = visualLook.eulerAngles.x - 360; + launchTransform.localRotation = Quaternion.Euler(currentEulerX + launchAngle, 0, 0); + + var d = Vector3.Distance(new Vector3(endPosition.x, 0, endPosition.z), new Vector3(startPosition.x, 0, startPosition.z)); + var h = endPosition.y - startPosition.y; + var theta = launchAngle * Mathf.Deg2Rad; + var g = Physics.gravity.magnitude; + var v0 = Mathf.Sqrt((g * d * d) / (2 * Mathf.Cos(theta) * Mathf.Cos(theta) * (d * Mathf.Tan(theta) - h))); + + launchVelocity = CalculateVelocityFromAngleAndSpeed(startPosition, theta, v0); + break; + case LaunchType.FIXED_SPEED: + var launchPosition = launchTransform.position; + var x = Vector3.Distance(new Vector3(endPosition.x, 0, endPosition.z), new Vector3(launchPosition.x, 0, launchPosition.z)); + var y = endPosition.y - launchPosition.y; + var angle = CalculateAngleForFixedSpeed(x, y, launchSpeed); + + launchTransform.localRotation = Quaternion.Euler(-angle, 0, 0); + launchVelocity = launchTransform.forward * launchSpeed; + break; + default: + throw new ArgumentOutOfRangeException(); + } + + PredictLine(startPosition); + } + + private float CalculateAngleForFixedSpeed(float x, float y, float speed) + { + var g = Physics.gravity.magnitude; + var speedSq = speed * speed; + var underRoot = speedSq * speedSq - g * (g * x * x + 2 * y * speedSq); + + if (underRoot < 0) + { + Debug.LogError("Unreachable target with given speed."); + return 0; + } + + var root = Mathf.Sqrt(underRoot); + var angle1 = Mathf.Atan((speedSq + root) / (g * x)); + var angle2 = Mathf.Atan((speedSq - root) / (g * x)); + + var selectedAngle = Mathf.Min(angle1, angle2) * Mathf.Rad2Deg; + return selectedAngle; + } + + private Vector3 CalculateEndPosition() + { + var endPosition = launchTransform.position + transform.forward * (chargingGauge * distanceCoefficient); + Debug.DrawRay(endPosition, Vector3.down * rayDistance, Color.blue, 3f); + + if (Physics.Raycast(endPosition, Vector3.down, out var hit, rayDistance, hitLayer, QueryTriggerInteraction.Collide)) + { + Debug.DrawRay(hit.point, Vector3.down * rayDistance, Color.red, 3f); + return hit.point; + } + print("?"); + return endPosition; + } + + private Vector3 CalculateVelocityFromAngleAndSpeed(Vector3 startPosition, float angleRad, float speed) + { + var direction = launchTransform.forward; + direction.y = 0; + direction.Normalize(); + var vx = speed * Mathf.Cos(angleRad); + var vy = speed * Mathf.Sin(angleRad); + + var velocity = new Vector3(direction.x * vx, vy, direction.z * vx); + return velocity; + } + + private void PredictLine(Vector3 startPosition) + { + if (!isUsingPredictLine) return; + + UpdateLineRender(lineMaxPoint, (0, launchTransform.position)); + + var currentVelocity = launchVelocity; + var predictPosition = startPosition; + for (var i = 0; i < lineMaxPoint; i++) + { + currentVelocity = GetNextPredictedPosition(currentVelocity, 0f, lineInterval); + var nextPosition = predictPosition + currentVelocity * lineInterval; + + predictPosition = nextPosition; + UpdateLineRender(lineMaxPoint, (i, predictPosition)); + if (newHitMarker) + { + if (Physics.Raycast(predictPosition, Vector3.down, out var hit, rayDistance, hitLayer, QueryTriggerInteraction.Collide)) + { + newHitMarker.transform.position = hit.point; + var hitRotation = Quaternion.FromToRotation(Vector3.up, hit.normal); + newHitMarker.transform.rotation = Quaternion.Euler(90, 0, 0) * hitRotation; + } + } + } + } + + private Vector3 GetNextPredictedPosition(Vector3 currentVelocity, float drag, float increment) + { + currentVelocity += Physics.gravity * increment; + currentVelocity *= Mathf.Clamp01(1f - drag * increment); + return currentVelocity; + } + + private void UpdateLineRender(int count, (int point, Vector3 pos) pointPos) + { + predictedLine.positionCount = count; + predictedLine.SetPosition(pointPos.point, pointPos.pos); + } + + private IEnumerator LaunchCoolDown(float waitTime) { var time = 0f; - cannonProcessBar.SetSliderValue(0f); - cannonProcessBar.SetActiveReloadSlider(true); + launchProcessBar.SetSliderValue(0f); + launchProcessBar.SetActiveReloadSlider(true); while (time <= waitTime) { time += Time.deltaTime; var sliderValue = time > 0 ? time / waitTime : 0f; - cannonProcessBar.SetSliderValue(sliderValue); + launchProcessBar.SetSliderValue(sliderValue); yield return null; } isReloading = false; - cannonProcessBar.SetActiveReloadSlider(false); + launchProcessBar.SetActiveReloadSlider(false); } - private void Fire(float chargingGauge) + private void Launch() { VisualFeedbackManager.Inst.CameraShake(CameraManager.Inst.OceanCamera.BaseShipCam, cameraShakePower, cameraShakeDuration); - var addAngle = chargingGauge * fireAngle; - var firePosRotation = firePos.rotation.eulerAngles; - firePosRotation.x -= addAngle; - var projectile = Instantiate(projectileObj, firePos.position, Quaternion.Euler(firePosRotation)); + var projectile = Instantiate(projectileObject, launchTransform.position, Quaternion.identity); var particleWeapon = projectile.GetComponent(); - particleWeapon.onHitAction.AddListener(HandleCannonHit); - projectile.GetComponent().velocity = projectile.transform.forward * launchSpeed; + particleWeapon.SetHitMarker(newHitMarker); + particleWeapon.onHitAction.AddListener(HitAction); + particleWeapon.Rb.AddForce(launchVelocity, ForceMode.VelocityChange); + + isReloading = true; } - private void HandleCannonHit(RaycastHit hit, float power) + private void HitAction(RaycastHit hit, float power, GameObject marker = null) { if (hit.collider.gameObject.layer == LayerMask.NameToLayer("Water")) { - var maxSize = Physics.OverlapSphereNonAlloc(hit.point, cannonRadius, hitColliders, targetLayer, + var maxSize = Physics.OverlapSphereNonAlloc(hit.point, cannonRadius, hitColliders, boidsLayer, QueryTriggerInteraction.Collide); for (var i = 0; i < maxSize; i++) { var hitBoids = hitColliders[i].GetComponentInParent(); - var catchSize = Random.Range((int)randomCatch.x, (int)randomCatch.y); + var catchSize = Random.Range((int)randomCatch.x, (int)randomCatch.y + 1); hitBoids.CatchBoid(hitColliders[i], catchSize); } } @@ -289,6 +476,11 @@ namespace BlueWaterProject { hit.transform.GetComponent()?.TakeDamage(power); } + + if (marker) + { + Destroy(marker); + } } #endregion diff --git a/BlueWater/Assets/02.Scripts/Weapon/ParticleWeapon.cs b/BlueWater/Assets/02.Scripts/Weapon/ParticleWeapon.cs index 9f8bdbb13..0331c0e29 100644 --- a/BlueWater/Assets/02.Scripts/Weapon/ParticleWeapon.cs +++ b/BlueWater/Assets/02.Scripts/Weapon/ParticleWeapon.cs @@ -23,18 +23,19 @@ namespace BlueWaterProject [ShowIf("@useAutoDestroy")] [SerializeField] private float autoDestroyTime = 5f; - public UnityEvent onHitAction; - + public UnityEvent onHitAction; + + private GameObject marker; private float power; private float detectionDistance; - private Rigidbody rb; + public Rigidbody Rb { get; private set; } private SphereCollider sphereCollider; private void OnDrawGizmosSelected() { var radius = sphereCollider ? sphereCollider.radius : colliderRadius; - var direction = rb ? rb.velocity.normalized : transform.forward; + var direction = Rb ? Rb.velocity.normalized : transform.forward; Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, radius); // Draws the start sphere @@ -43,7 +44,7 @@ namespace BlueWaterProject private void Awake() { - rb = GetComponent(); + Rb = GetComponent(); sphereCollider = GetComponent(); } @@ -65,9 +66,9 @@ namespace BlueWaterProject private void FixedUpdate() { - if (rb.velocity.magnitude != 0) + if (Rb.velocity.magnitude != 0) { - transform.rotation = Quaternion.LookRotation(rb.velocity); // Sets rotation to look at direction of movement + transform.rotation = Quaternion.LookRotation(Rb.velocity); // Sets rotation to look at direction of movement } float radius; // Sets the radius of the collision detection @@ -76,12 +77,12 @@ namespace BlueWaterProject else radius = colliderRadius; - var direction = rb.velocity; // Gets the direction of the projectile, used for collision detection - if (rb.useGravity) + var direction = Rb.velocity; // Gets the direction of the projectile, used for collision detection + if (Rb.useGravity) direction += Physics.gravity * Time.deltaTime; // Accounts for gravity if enabled direction = direction.normalized; - detectionDistance = rb.velocity.magnitude * Time.deltaTime; // Distance of collision detection for this frame + detectionDistance = Rb.velocity.magnitude * Time.deltaTime; // Distance of collision detection for this frame if (Physics.SphereCast(transform.position, radius, direction, out var hit, detectionDistance, targetLayer)) // Checks if collision will happen { @@ -107,7 +108,7 @@ namespace BlueWaterProject } else { - onHitAction.Invoke(hit, power); + onHitAction.Invoke(hit, power, marker); } Destroy(projectileParticle, 3f); // Removes particle effect after delay @@ -118,5 +119,6 @@ namespace BlueWaterProject public void SetPower(float value) => power = value; + public void SetHitMarker(GameObject value) => marker = value; } } \ No newline at end of file diff --git a/BlueWater/Assets/03.Materials/LaunchHitMarker.mat b/BlueWater/Assets/03.Materials/LaunchHitMarker.mat new file mode 100644 index 000000000..46e67ba82 --- /dev/null +++ b/BlueWater/Assets/03.Materials/LaunchHitMarker.mat @@ -0,0 +1,143 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-4858898327941927310 +MonoBehaviour: + m_ObjectHideFlags: 11 + 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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 9 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LaunchHitMarker + m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 1 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - MOTIONVECTORS + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: d18c78739df93af4e8e741c9d1467a29, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: d18c78739df93af4e8e741c9d1467a29, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 0 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 0 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossinessSource: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Shininess: 0 + - _Smoothness: 0.5 + - _SmoothnessSource: 0 + - _SmoothnessTextureChannel: 0 + - _SpecSource: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 5 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _WorkflowMode: 1 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 1, g: 0, b: 0, a: 1} + - _Color: {r: 1, g: 0, b: 0, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/BlueWater/Assets/03.Materials/LaunchHitMarker.mat.meta b/BlueWater/Assets/03.Materials/LaunchHitMarker.mat.meta new file mode 100644 index 000000000..85a027468 --- /dev/null +++ b/BlueWater/Assets/03.Materials/LaunchHitMarker.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ec0306384204dd40a1dc4b93f4e7317 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/BlueWater/Assets/05.Prefabs/Boids/Boids.prefab b/BlueWater/Assets/05.Prefabs/Boids/Boids.prefab index f74fd2770..0940c35b7 100644 --- a/BlueWater/Assets/05.Prefabs/Boids/Boids.prefab +++ b/BlueWater/Assets/05.Prefabs/Boids/Boids.prefab @@ -158,6 +158,7 @@ MonoBehaviour: showBounds: 1 fishSpot: {fileID: 6023135201199208214} showWaterEffect: 1 + isUsingDynamicHeight: 0 fishSpotOffset: {x: 0, y: 0, z: 0} contentUiPrefab: {fileID: 3090447943159425444, guid: ff7dbfdf9bd0ee5499f523f8fafa45f7, type: 3} @@ -236,6 +237,11 @@ PrefabInstance: propertyPath: m_ConstrainProportionsScale value: 1 objectReference: {fileID: 0} + - target: {fileID: 3990893376361859224, guid: 0051ffdc4c5db0d439d5d2c880040228, + type: 3} + propertyPath: m_IsTrigger + value: 1 + objectReference: {fileID: 0} - target: {fileID: 4617604176008979014, guid: 0051ffdc4c5db0d439d5d2c880040228, type: 3} propertyPath: m_ConstrainProportionsScale diff --git a/BlueWater/Assets/05.Prefabs/HitMarker.prefab b/BlueWater/Assets/05.Prefabs/HitMarker.prefab new file mode 100644 index 000000000..e9fad27ed --- /dev/null +++ b/BlueWater/Assets/05.Prefabs/HitMarker.prefab @@ -0,0 +1,87 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &5951017876843886146 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8173673222374022247} + - component: {fileID: 132518609203318759} + - component: {fileID: 1700303181779377356} + m_Layer: 7 + m_Name: HitMarker + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8173673222374022247 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5951017876843886146} + serializedVersion: 2 + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 1 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &132518609203318759 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5951017876843886146} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1700303181779377356 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5951017876843886146} + 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_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 2ec0306384204dd40a1dc4b93f4e7317, 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} diff --git a/BlueWater/Assets/05.Prefabs/HitMarker.prefab.meta b/BlueWater/Assets/05.Prefabs/HitMarker.prefab.meta new file mode 100644 index 000000000..109ab2c33 --- /dev/null +++ b/BlueWater/Assets/05.Prefabs/HitMarker.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0eef5d11a5bdac248b2d16d733fd357c +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeFireOBJ.prefab b/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeFireOBJ.prefab index 65ec58eb1..cf41ed1f3 100644 --- a/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeFireOBJ.prefab +++ b/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeFireOBJ.prefab @@ -28,7 +28,7 @@ Transform: m_GameObject: {fileID: 128572} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 8.313633, y: 5.892903, z: -13.319157} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 1 m_Children: [] @@ -53,7 +53,7 @@ SphereCollider: m_ProvidesContacts: 0 m_Enabled: 1 serializedVersion: 3 - m_Radius: 0.15 + m_Radius: 1 m_Center: {x: 0, y: 0, z: 0} --- !u!54 &5479992 Rigidbody: @@ -99,7 +99,7 @@ MonoBehaviour: type: 3} muzzleParticle: {fileID: 1509306094841910, guid: 7026fe0f1c7efa648b9b3c4662359062, type: 3} - colliderRadius: 0.15 + colliderRadius: 1 collideOffset: 0.1 targetLayer: serializedVersion: 2 diff --git a/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeMissileFire.prefab b/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeMissileFire.prefab index 473bbe106..a49439d72 100644 --- a/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeMissileFire.prefab +++ b/BlueWater/Assets/05.Prefabs/Particles/GrenadeFire/GrenadeMissileFire.prefab @@ -9895,7 +9895,7 @@ ParticleSystem: startSize: serializedVersion: 2 minMaxState: 0 - scalar: 0.32 + scalar: 0.4 minScalar: 1 maxCurve: serializedVersion: 2 diff --git a/BlueWater/Assets/Epic Toon FX/Materials/Misc/Bubbles/bubble_half_clear_AB.mat b/BlueWater/Assets/Epic Toon FX/Materials/Misc/Bubbles/bubble_half_clear_AB.mat index dbeee96ee..f340cb3e6 100644 --- a/BlueWater/Assets/Epic Toon FX/Materials/Misc/Bubbles/bubble_half_clear_AB.mat +++ b/BlueWater/Assets/Epic Toon FX/Materials/Misc/Bubbles/bubble_half_clear_AB.mat @@ -74,7 +74,7 @@ Material: - _DistortionBlend: 0.5 - _DistortionEnabled: 0 - _DistortionStrength: 1 - - _DistortionStrengthScaled: 0 + - _DistortionStrengthScaled: 0.1 - _DstBlend: 10 - _DstBlendAlpha: 10 - _EmissionEnabled: 0