W298.dev
ProjectsPostsAbout Me
youtube
Pages
ProjectsPostsAbout Me
Posts
TAGS
All
RL-Obstacle-Avoid
RL-Competitive
Robot-Escape
Assembly Definition
ML-Agent
RL-Obstacle-Avoid
RL-Competitive
Unity
RL-Obstacle-Avoid
RL-Competitive
Robot-Escape
Assembly Definition
SERIES
RL-Obstacle-Avoid
RL-Competitive
Robot-Escape

Ammo & Reload

Ammo System

GunController 안에 AmmoSystem Class 를 따로 구현했다. canReload 는 남은 탄약이 있고, 현재 장전된 탄약이 탄창 용량보다 작으면 true
1public class AmmoSystem
2{
3    public int magAmmo;
4    public int magCapacity;
5    public int remainAmmo;
6
7    public bool canReload { get => this.remainAmmo > 0 && this.magAmmo < this.magCapacity; }
8
9    public AmmoSystem(int magCapacity, int totalAmmo)
10    {
11        this.magAmmo = magCapacity;
12        this.magCapacity = magCapacity;
13        this.remainAmmo = totalAmmo - magAmmo;
14    }
15
16    public void Reload()
17    {
18        int addAmmo = this.magCapacity - this.magAmmo;
19
20        if (this.remainAmmo < addAmmo)
21        {
22            addAmmo = this.remainAmmo;
23            this.remainAmmo = 0;
24        }
25        else
26        {
27            this.remainAmmo -= addAmmo;
28        }
29
30        this.magAmmo += addAmmo;
31    }
32}
33
1public class GunController : MonoBehaviour
2{
3	...
4    public int magCapacity = 30;
5    public int totalAmmo = 60;
6	public AmmoSystem ammoSystem;
7
8    private void Start()
9    {
10    	...
11        ammoSystem = new AmmoSystem(magCapacity, totalAmmo);
12    }
13
14    private void FireWeapon()
15    {
16    	if (ammoSystem.magAmmo <= 0) return;
17        ammoSystem.magAmmo--;
18
19        ...
20    }
21
22    public void OnReload()
23    {
24    	ammoSystem.Reload();
25    }
26}
27

Reload

Input 처리

1public class RobotInputHandler : MonoBehaviour
2{
3	...
4	public InputAction reloadAction;
5
6	private void Start()
7    {
8    	...
9    	reloadAction.Enable();
10        ...
11
12        reloadAction.performed += context =>
13        {
14        	if (!gunController.ammoSystem.canReload) return;
15            reloadEvent.Invoke();
16        }
17    }
18}
19
1public class RobotAnimationController : MonoBehaviour
2{
3	public void OnReload()
4    {
5        animator.SetBool("isReload", true);
6    }
7}
8
https://velog.velcdn.com/images/lutca1320/post/e3482d26-f3f3-48fd-a04c-4bf9407e2cf9/image.png
Input 처리 코드를 작성해 주었다.

Animation Out

Reload 애니메이션을 제어하기 위해 animator 에 ReloadController 를 부착했다.
  • Reload 애니메이션이 끝나면 자동으로 isReload 값을 false 로 설정한다.
  • 원래 조준하고 있었으면 조준한 상태로 장전한다. (aimReload 변수)
  • 장전 도중 조준하면 장전이 중단 (Interrupted) 된다.
  • 장전 애니메이션이 성공적으로 완료되면 GunController 클래스의 OnReload 함수를 실행시킨다.
1public class ReloadController : StateMachineBehaviour
2{
3    private bool aimReload = false;
4
5    public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
6    {
7        aimReload = animator.GetBool("isAim");
8    }
9
10    public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
11    {
12        if (!aimReload && animator.GetBool("isAim"))
13        {
14            animator.SetBool("isReload", false);
15        }
16
17        if (stateInfo.normalizedTime > 1)
18        {
19            animator.transform.GetComponentInChildren<GunController>().OnReload();
20            animator.SetBool("isReload", false);
21        }
22    }
23
24    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
25    {
26        animator.SetBool("isReload", false);
27    }
28}
29
  • 재장전 성공
    https://velog.velcdn.com/images/lutca1320/post/9435f69f-d76e-496a-847a-f7ae91d6514c/image.gif
  • 재정전 중단 (Interrupted)
    https://velog.velcdn.com/images/lutca1320/post/e1b41df5-49fc-4e68-8d18-f9f97f7e5cc9/image.gif
  • 조준 중 재장전
    https://velog.velcdn.com/images/lutca1320/post/225f6abe-8aa8-4cce-80e6-fa58d69ac1ac/image.gif

Animation Mask 설정

걸으면서, 앉아서, 서서, 뛰면서 Reload 애니메이션이 재생되도록 하기 위해서 Animation Mask 설정을 해 주었다.
https://velog.velcdn.com/images/lutca1320/post/1af7f791-0f99-4b42-96b8-67f5cadc95e3/image.png
본 상단만 애니메이션을 적용시키기 위해 위와 같이 설정했다.
https://velog.velcdn.com/images/lutca1320/post/662e7421-95b5-47fa-aea0-85cdfa8fda0f/image.png
  • 뛰면서 장전
    https://velog.velcdn.com/images/lutca1320/post/1e013de4-ddf0-4dd7-be97-7c1d53535afe/image.gif
  • 앉아서 장전
    https://velog.velcdn.com/images/lutca1320/post/fb914854-65cf-4b4a-a32b-7408af888d1d/image.gif
  • 조준하면서 (걸으며) 장전
    https://velog.velcdn.com/images/lutca1320/post/427094ac-1f24-4fcd-96b9-74bb7705dcfa/image.gif