티스토리 뷰

혼란하다 혼란해




유니티 에셋스토어의 공짜 모델인 좀비를 가지고 간단한 게임을 만들어봤습니다.

좀비 에셋은 여기서 받으실 수 있어요!

https://www.assetstore.unity3d.com/kr/?stay#!/content/30232


어떻게 진행되냐면 

게임을 실행하면 좀비프리팹을 생성해서 랜덤으로 맵에 뿌려주고


캐릭터는 이동과 점프만 해주면 좀비가 가까이있으면 알아서 달려가서 자동으로 전투를 행합니다.

좀비는 세대 때리면 죽고,

죽을 때 땅에 몸이 묻히는 버그가 있지만 애니메이션의 문제니까 그냥 냅뒀습니다 ㅎㅎ


그리고 캐릭터의 주변을 펫 개념으로 뭔가가 공전하고 있고

아무런 영향은 끼치지 못합니다.

해당 부분은 로테이트어라운드로 했습니다.


몬스터 찾는 건

몬스터 전체에 접근해서 가장 가까운 녀석을 골라서 걔가 최대 범위보다 가까우면 타겟으로 설정해서 전투 모드가 됩니다.


퀄리티가 높게 만든 것도 아니고 연습용으로 빠르게 만든건데

사실 괜히 좀비물이 재밌게 느껴지네요.

죄의식도 안 느껴지고...




소스는 별로 예쁘게 안만들었지만 그래도 올려봅니다!



주인공 스크립트입니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
using System.Collections.Generic;
using System.Collections;
using UnityEngine;
 
public class Hero : MonoBehaviour
{
    public static Hero Intstance;
    public enum eHeroState
    {
        Idle,
        Move,
        MoveToAttack,
        Attack,
        Jump,
    }
    [SerializeField]
    Transform camTrans;
    CharacterController cc;
    public Animation anim;
    public float rotateSpeed = 90;
    public float moveSpeed = 3;
    public float attackRange = 0.5f;
    Vector3 moveDir;
    Vector3 deltaPos;
    public Transform cubeTrans;
    public eHeroState state;
    Coroutine nowCoroutine;
 
    private void Awake()
    {
        cc = GetComponent<CharacterController>();
    }
 
    void Start()
    {
        nowCoroutine = StartCoroutine(Detect());
        state = eHeroState.Idle;
        deltaPos = transform.position;
    }
 
    void Attack(Transform monTrans)
    {
 
    }
 
    public IEnumerator Detect()
    {
        while (true)
        {
            if (cc.isGrounded)
            {
 
                var mons = GameObject.FindObjectsOfType<Monster>();
                if (mons.Length > 0)
                {
                    float distance = 0;
                    int disnum = -1;
                    for (int i = 0; i < mons.Length; i++)
                    {
                        float nowDis = (transform.position - mons[i].transform.position).sqrMagnitude;
                        if (mons[i].hp > 0 && (disnum == -1 || distance > nowDis))
                        {
                            disnum = i;
                            distance = nowDis;
                        }
                    }
                    if (distance < 2 && disnum != -1)
                    {
                        targetMonster = mons[disnum];
                        state = eHeroState.MoveToAttack;
                        nowCoroutine = StartCoroutine(MoveToAttack());
                        break;
                    }
                }
            }
            yield return new WaitForSeconds(0.1f);
        }
    }
    public IEnumerator MoveToAttack()
    {
        while (true)
        {
            moveDir = (targetMonster.transform.position - transform.position+new Vector3(0.2f,0,0.2f)).normalized*moveSpeed;
            anim.Play("run@loop");
            transform.rotation = Quaternion.Euler(090 - Mathf.Atan2(moveDir.z, moveDir.x) * Mathf.Rad2Deg, 0);
            if((targetMonster.transform.position - transform.position).magnitude < attackRange)
            {
                moveDir = Vector3.zero;
                state = eHeroState.Attack;
                nowCoroutine = StartCoroutine(AttackMonster());
                break;
            }
            yield return null;
        }
    }
 
    public IEnumerator AttackMonster()
    {
        while (true)
        {
            transform.LookAt(new Vector3(targetMonster.transform.position.x,transform.position.y, targetMonster.transform.position.z ));
            anim.Play("attack_sword_01");
            yield return new WaitForSeconds(0.3f);
 
            bool re = targetMonster.Damage(this10);
            yield return new WaitForSeconds(0.6f);
            if (!re)
            {
                state = eHeroState.Idle;
                nowCoroutine = StartCoroutine(Detect());
                break;
            }
        }
        
 
    }
 
    Monster targetMonster;
 
 
    public void Hit()
    {
        targetMonster.Damage(this10);
    }
 
 
    void Update()
    {
        //moveDir = Vector3.zero;
        if (state == eHeroState.Idle || state == eHeroState.Move)
        {
            if (cc.isGrounded)
            {
                if (Input.GetButtonDown("Jump"))
                {
 
                    anim.Play("jump");
                    moveDir.y += 5;
 
                }
                else
                {
                    float h = Input.GetAxisRaw("Horizontal");
                    float v = Input.GetAxisRaw("Vertical");
                    //moveDir = transform.TransformDirection(moveDir);
 
                    moveDir = new Vector3(h, 0, v).normalized * moveSpeed;
                    if (Mathf.Abs(h) > 0.3f || Mathf.Abs(v) > 0.3f)
                    {
                        state = eHeroState.Move;
                        anim.Play("run@loop");
                        transform.rotation = Quaternion.Euler(090 - Mathf.Atan2(moveDir.z, moveDir.x) * Mathf.Rad2Deg, 0);
 
                    }
                    else
                    {
                        state = eHeroState.Idle;
                        anim.Play("idle@loop");
                    }
                }
            }
 
        }
 
        moveDir.y += Physics.gravity.y * Time.deltaTime;
        cc.Move(moveDir * Time.deltaTime);
        var cv = transform.position - deltaPos;
        cv.y = 0;
        cubeTrans.position += cv;
        camTrans.position += cv;
        deltaPos = transform.position;
    }
}
 
cs


몬스터 스크립트입니다. 맞기만 하고 공격은 안합니다. (맞는 애니메이션이 어택이라고 써져있는거임)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Monster : MonoBehaviour {
    [SerializeField]
    Animator anim;
 
    public int hp = 100;
 
    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }
    public bool Damage(Hero hero, int attackPower)
    {
        anim.Play("attack");
        transform.LookAt(hero.transform);
        hp -= attackPower;
        if(hp <= 0)
        {
            Dead();
            return false;
        }
        return true;
    }
    void Dead()
    {
        //GetComponent<CapsuleCollider>().enabled = false;
        transform.position += new Vector3(00.1f, 0);
        anim.Play("fallingback");
    }
}
cs


주변 도는 녀석입니다. 원래 큐브였어서 클래스이름이 큐브입니다 ㅋ


1
2
3
4
5
6
7
8
9
10
11
12
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Cube : MonoBehaviour {
    public Transform target;
 
    void Update () {
        transform.RotateAround(target.position, Vector3.up, 90 * Time.deltaTime);
        transform.position = new Vector3(transform.position.x, 1, transform.position.z);
    }
}
cs


몬스터 소환하는 부분입니다.

이 부분은 특히 최적화 안했지만 연습 문제라 그냥 냅둡니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class MonsterManager : MonoBehaviour {
    void Start () {
        GameObject o = (GameObject)Resources.Load("Monster");
        for (int i = 0; i < 30; i++)
        {
            Instantiate(o, new Vector3(Random.Range(-10f, 10f), 0.03f, Random.Range(-10f, 10f)), Quaternion.Euler(0, Random.Range(-180f, 180f), 0), transform);
        }
    }
}
cs



참고로 훨씬 쉽고 깔끔하게 코딩할 수 있으니

이해만 하시고 따라 치지 마시길 바랍니다.

코드 자체는 별로에요~~

댓글
최근에 올라온 글
Total
Today
Yesterday
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31