Commit 18049a31 authored by 15박보승's avatar 15박보승

Implementing weapon system.

parent d7bdc6ba
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BloodParticleMaterial
m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AlphaTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- PixelSnap: 0
- _EnableExternalAlpha: 0
m_Colors:
- _Color: {r: 1, g: 0, b: 0, a: 1}
- _Flip: {r: 1, g: 1, b: 1, a: 1}
- _RendererColor: {r: 1, g: 1, b: 1, a: 1}
fileFormatVersion: 2
guid: a537af3ab109b2b4891f4033f51de915
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
%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: 27849484d6b326e4abb8591c36ef24b4, type: 3}
m_Name: DummyAssaultRifle
m_EditorClassIdentifier:
shotRange: 5
shotInterval: 1
damage: 10
damageRandomRange: 1
bulletsPerShot: 3
bulletInterval: 0.1
fileFormatVersion: 2
guid: 73594f3ebba70a94d92c2cdbf0384f9f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
......@@ -36,12 +36,21 @@ public abstract class Actor : MonoBehaviour
}
set
{
if (_health > value)
hitParticle.Play();
_health = value;
if (_health <= 0)
gameObject.SetActive(false);
}
}
[SerializeField]
protected ParticleSystem hitParticle;
protected virtual void Start()
{
agent = GetComponent<NodalPathfinding2DAgent>();
Health = MaxHealth;
}
public virtual void MoveTo(Vector2 destination)
......
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using UnityEngine;
using BS;
using System.Linq;
enum CharacterControlMode
{
......@@ -13,26 +14,19 @@ enum CharacterControlMode
[RequireComponent(typeof(LineRenderer))]
public abstract class PlayableCharacter : Actor
{
public float shotRange = 5.0f;
public LayerMask shotBlockMask;
protected LineRenderer shotRangeRenderer;
[SerializeField]
protected LineRenderer pathRenderer;
private float r = 0.0f;
private WeaponBehaviour weaponBehaviour = null;
public bool isSelected = false;
private Transform target;
public Enemy Target { private get; set; }
public bool isAutoTargeting = false;
public LayerMask enemyMask;
protected override void Start()
{
base.Start();
if (shotRangeRenderer == null)
shotRangeRenderer = GetComponent<LineRenderer>();
if (pathRenderer == null)
pathRenderer = GetComponentInChildren<LineRenderer>();
if (weaponBehaviour == null)
weaponBehaviour = GetComponent<WeaponBehaviour>();
if (selectRing == null)
selectRing = transform.Find("SelectRing").gameObject;
}
......@@ -41,38 +35,32 @@ public abstract class PlayableCharacter : Actor
{
if (isSelected)
{
r = Mathf.Min(shotRange, r + shotRange * Time.deltaTime);
Vector3[] vertices = new Vector3[361];
for (int i = 0; i < 360; i++)
{
Vector2 direction = (Quaternion.Euler(0, 0, i) * Vector2.right).normalized;
RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, r, shotBlockMask);
if (hit.collider != null)
vertices[i] = hit.point;
else
vertices[i] = transform.position + new Vector3(direction.x, direction.y) * r;
}
vertices[360] = vertices[0];
shotRangeRenderer.SetPositions(vertices);
weaponBehaviour.DrawWeaponRange();
}
if (isAutoTargeting && Target == null)
{
AutoTargeting();
}
if (Target != null)
{
AttackTarget();
}
}
public override void OnSelected()
{
if (isSelected)
return;
isSelected = true;
shotRangeRenderer.enabled = true;
selectRing?.SetActive(true);
r = 0;
weaponBehaviour.OnSelected();
}
public override void OnUnselected()
{
isSelected = false;
shotRangeRenderer.enabled = false;
selectRing?.SetActive(false);
weaponBehaviour.OnDeselected();
}
public override void MoveTo(Vector2 destination)
......@@ -81,9 +69,44 @@ public abstract class PlayableCharacter : Actor
agent.MoveTo(destination);
}
public void DrawPath()
public void AutoTargeting()
{
Collider2D[] result = Physics2D.OverlapCircleAll(transform.position, weaponBehaviour.weapon.shotRange,enemyMask);
List<Collider2D> sorted = result.ToList();
sorted.Sort((a, b) =>
Vector2.Distance(transform.position, a.transform.position) > Vector2.Distance(transform.position, b.transform.position) ? 1 : -1);
foreach(var enemy in sorted)
{
}
}
public void SetTarget(Enemy enemy)
{
if(isSelected)
Target = enemy;
}
public void AttackTarget()
{
if (weaponBehaviour.IsAttackable(Target))
{
agent.Stop();
LookAt(Target.transform);
weaponBehaviour.OnAttack(Target);
}
else
{
agent.MoveTo(Target.transform.position);
}
}
protected void LookAt(Transform target)
{
transform.rotation = Quaternion.Euler(0, 0, Vector2.SignedAngle(Vector2.up, target.position - transform.position));
}
protected abstract void DefaultControl();
......
......@@ -90,6 +90,13 @@ namespace BS {
}
}
public void Stop()
{
rb.velocity = Vector2.zero;
destination = transform.position;
path.Clear();
}
private void FixedUpdate()
{
if (path.Count > 0)
......
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class PlayerController : SingletonBehaviour<PlayerController>
......@@ -23,6 +24,7 @@ public class PlayerController : SingletonBehaviour<PlayerController>
private void Awake()
{
characters = FindObjectsOfType<PlayableCharacter>().ToList();
}
private void Update()
......@@ -119,9 +121,22 @@ public class PlayerController : SingletonBehaviour<PlayerController>
}
if (Input.GetMouseButton(1))
{
foreach (var character in characters)
Vector3 mouseWorldPostion = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Enemy target = Physics2D.OverlapPoint(mouseWorldPostion).GetComponent<Enemy>();
if (target != null)
{
character.MoveTo(Camera.main.ScreenToWorldPoint(Input.mousePosition));
foreach (var character in characters)
{
character.SetTarget(target);
}
}
else
{
foreach (var character in characters)
{
character.MoveTo(Camera.main.ScreenToWorldPoint(Input.mousePosition));
character.SetTarget(null);
}
}
}
}
......
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : ScriptableObject
{
public float shotRange;
public float damage;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AssaultRifle : Weapon
{
public int bulletsPerShot;
public float bulletInterval;
public override void OnAttack(Enemy enemy)
{
if (IsReady)
{
behaviour.StartCoroutine(ShotBullet(enemy));
shotTimer = shotInterval;
}
}
private IEnumerator ShotBullet(Enemy enemy)
{
for (int i = 0; i < bulletsPerShot; i++)
{
enemy.Health -= damage + Random.Range(-damageRandomRange, damageRandomRange + 1);
behaviour.EmitBulletParticle();
yield return new WaitForSeconds(bulletInterval);
}
}
}
fileFormatVersion: 2
guid: 27849484d6b326e4abb8591c36ef24b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class Weapon : ScriptableObject
{
protected WeaponBehaviour behaviour;
public float shotRange;
public float shotInterval;
protected float shotTimer;
public int damage;
public int damageRandomRange;
public bool IsReady { get { return shotTimer <= 0; } }
public virtual void Init(WeaponBehaviour behaviour)
{
this.behaviour = behaviour;
shotTimer = shotInterval;
}
public virtual void UpdateWeapon(float deltaTime)
{
shotTimer = Mathf.Max(0, shotTimer - deltaTime);
}
public abstract void OnAttack(Enemy enemy);
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public sealed class WeaponBehaviour : MonoBehaviour
{
[SerializeField]
private List<Weapon> weapons = new List<Weapon>();
[SerializeField]
private int weaponIndex = 0;
[SerializeField]
private LineRenderer shotRangeRenderer;
public LayerMask shotBlockMask;
[SerializeField]
private ParticleSystem bulletParticle;
public Action<Enemy> OnAttack { get; private set; }
public Action OnReload { get; private set; }
public Weapon weapon { get { return weapons[weaponIndex]; } }
private float shotRadius = 0;
private void Start()
{
ChangeWeapon(weaponIndex);
}
private void Update()
{
weapon.UpdateWeapon(Time.deltaTime);
}
public void Init(Weapon weapon)
{
weapon.Init(this);
OnAttack = weapon.OnAttack;
}
public void ChangeWeapon(int index)
{
if (index >= weapons.Count)
{
Debug.LogError("Index out of bounds");
return;
}
Init(weapons[index]);
}
public void EmitBulletParticle()
{
bulletParticle.Emit(1);
}
public void DrawWeaponRange()
{
shotRadius = Mathf.Min(weapon.shotRange, shotRadius + weapon.shotRange * Time.deltaTime);
Vector3[] vertices = new Vector3[361];
for (int i = 0; i < 360; i++)
{
Vector2 direction = (Quaternion.Euler(0, 0, i) * Vector2.right).normalized;
RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, shotRadius, shotBlockMask);
if (hit.collider != null)
vertices[i] = hit.point;
else
vertices[i] = transform.position + new Vector3(direction.x, direction.y) * shotRadius;
}
vertices[360] = vertices[0];
shotRangeRenderer.SetPositions(vertices);
}
public void OnSelected()
{
shotRadius = 0;
shotRangeRenderer.enabled = true;
}
public void OnDeselected()
{
shotRangeRenderer.enabled = false;
}
public bool IsAttackable(Enemy enemy)
{
return !(Vector2.Distance(transform.position, enemy.transform.position) > weapon.shotRange) &&
!Physics2D.Linecast(transform.position, enemy.transform.position, shotBlockMask);
}
}
fileFormatVersion: 2
guid: 4ecc7f8bb7cb0ba4abf7b037c9a61411
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -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: fffdfffffffdfffffffdfffffffffffffffdfffffffdfffffffffffffffffffffffdffffc8fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_LayerCollisionMatrix: fffdfffffffdfffffffdfffffffffffffffdfffffffdfffffffffffffffffffffffdffffc8f0fffffffdfffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
......@@ -15,8 +15,8 @@ TagManager:
-
- Wall
- Floor
-
-
- Enemy
- Player
-
-
-
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment