• Страница 1 из 1
  • 1
Форум » Unity3D » Уроки » Реализовываем рубку деревьев
Реализовываем рубку деревьев
Badman · OfflineДобавлено 04.08.2014 в 16:33 · Пост #1
Рубку деревьев можно реализовать двумя способами - через триггеры или через Raycast.
Способ первый:

Создаём простую сцену,делаем террейн , освещение и т.д . Берём модель дерева , приделал капсульный колайдер по форме ствола и ещё один боксовый поперёк на листву(чтобы после падения оно не катилось вдоль капсульного колайдера) , добавляем Rigidbody и делаем true параметр IsKinematic , это значит что на дерево не влияет физика и когда надо мы его отключаем , чтобы соответственно физика появилась.Добавляем в префаб готовое дерево:

Код
function OnTriggerStay (other : Collider) {      // фунция работы с триггерами  
if(other.gameObject.name=="Palm"){   //проверяем наличие в триггере объекта с иминем "Palm"  
if(Input.GetMouseButtonDown(0)){   //при нажатии на ЛКМ..  
other.rigidbody.isKinematic = false;    //отключаем параметр isKinematic  
}  
}  
}


Ложем скрипт на камеру стандартного Fist Person Controller'а и приделываем на неё (камеру) Колайдер-зону где игрок как-бы размахивает топором , ставим параметр IsTrigger и всё, когда персонаж подходит к дереву и нажимает левую кнопку мыши , то у дерева отключается игнор физики , а так как ствол состоит из капсулы , то оно непременно упадёт(надо малейшая неровность) , если хотите можете к дереву силу приложить AddForce , но оно и так падает вполне естественно , я поставил на него массу в 5 , всё очень просто. Забыл добавить что надо указать имя дереву "Palm" если хотите использовать мой код , так же можете работать через тег , для этого вместо if(other.gameObject.name=="Palm"){ надо if(other.gameObject.tag=="Palm"){

Способ второй(Можно на этой же сцене)

Создаем C# скрипт:

Код
using UnityEngine;  
using System.Collections;  

public class Name : MonoBehaviour {  

             void Start () {           
                Screen.showCursor = false; //скрываем курсор(необязательно)  
             }           

             void Update () {           
                Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0)); //проводим луч от  
           // камеры по вектору центра экрана  
                RaycastHit hit; //определяем луч в переменную  
                          
                if(Physics.Raycast(ray,out hit,5f) && hit.collider.tag == "palm")  // если луч длиной 5 юнов упёрся в колайдер с // тегом "palm" то  
                {             
                   if(Input.GetMouseButtonUp(0)&& hit.collider.rigidbody.isKinematic == true ) // если мы нажимаем ЛКМ и на           
// пальме включен режим игнора физики( isKinematic) то  
                   {           
                      hit.collider.rigidbody.isKinematic = false; // включаем взаимодействие с физикой  
                      hit.collider.rigidbody.AddRelativeForce(0, 0, 5); // применяем силу к пальме по лок. координатам , чтобы            
// охотнее падала))           
                   }  
                }  
             }  
}


Перетаскиваем скрипт на персонажа (не забудте убрать триггер , который описан в первом способе ,а то работать не будет).Ставим массу пальме 5 и теперь она будет падать "по любому" от одного удара.
Вскоре я обновлю тему , сделаю счётчик ударов для каждой пальмы (чтобы не ломалась после одного удара )
сделаю деревьям пеньки , которые будут оставаться после срубки и мини инвентарь , который показывает число нарубленных брёвен (начисляться будут после ударов уже поваленного дерева и после нного кол-ва ударов дерево будет исчезать), реализация самого топора со звуками при ударе о дерево и анимацией.Вот такой несложный урок получился , спасибо за то что прочли , оставляйте отзывы и пишите чего бы вы хотели увидеть . fellow

Продолжаем ! Сейчас мы реализуем накопительную систему для каждого дерева  ,чтобы только после определённого кол-ва ударов оно упало.Для этого откроем наш прошлый скрипт с raycast'ами и кое что поменяем : 

Код
using UnityEngine;  
using System.Collections;  

public class AttackeWood : MonoBehaviour {  
        // Use this for initialization      
        void Start () {      
           Screen.showCursor = false;      
        }      
             
        // Update is called once per frame      
        void Update () {      
           Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));      
           RaycastHit hit;      
                
           if(Physics.Raycast(ray,out hit,5f) && hit.collider.tag == "palm")      
           {        
              var to = hit.collider.GetComponent<stat>(); //вводим в переменную компонент stat  ,который мы сейчас напишем  
              if(Input.GetMouseButtonUp(0)&& to.poval == false ) //если мы нажимаем на ЛКМ и дерево ещё не повалено     
              {      
                 to.volume -= 1;//отнимаем в будующем скрипте переменную на 1  
              }  
           }  
        }  
}


Так , со старым скриптом мы разобрались , теперь создадим новый C# и назовём его stat:

Код
using UnityEngine;  
using System.Collections;  

public class stat : MonoBehaviour {  
        public int volume = 5; //назначаем кол-во ударов , необходимое для срубки  
        public bool poval = false;  //данное состояние дерева , false -не повалено , true - повалено  
// далее , думаю всё понятно  
        void Update () {  
        if (volume == 0) {  
              poval = true;  
              rigidbody.isKinematic = false;      
              rigidbody.AddRelativeForce(0, 0, 5);  
           }  
        }  
}


Скрипт перетаскиваем на пальму - дело сделано! После только 5 ударов дерево упадёт, далее займёмся системой пауз между ударов , чтобы их(удары) можно было наносить только спустя пару секунд.Оценивайте gamer

Привет! Реализуем паузы между ударами.
Возьмём всё тот же скрипт AttackeWood и встроем в него таймер : 

Код
using UnityEngine;  
using System.Collections;  

public class AttackeWood : MonoBehaviour {  
       // Use this for initialization     
       public float Timer = 1.7f; // кол-во сек между ударами  
       private float TimerDown;  
       public bool atk; //разрешение на удар  
       void Start () {     
          Screen.showCursor = false;     
          TimerDown = Timer; //Задаем временной переменной значение которое нужно отсчитать  
          atk = true; //С начала игры атака доступна  
       }     
           
       // Update is called once per frame     
       void Update () {     
                Ray ray = Camera.main.ScreenPointToRay (new Vector3 (Screen.width / 2, Screen.height / 2, 0));     
                RaycastHit hit;     
              
                if (Physics.Raycast (ray, out hit, 5f) && hit.collider.tag == "palm") {       
                      var to = hit.collider.GetComponent<stat> ();  
                      if (Input.GetMouseButtonUp (0) && to.poval == false && atk == true) { // кроме всего прочего если атака доступна  
                            atk = false; // запрещаем атаку  
                            to.volume -= 1;      
                      }  
                }  
                if (atk == false) { // если атака заблокировалась то     
                      if (TimerDown > 0) { // включаем таймер на 1.7 сек.  
                            TimerDown -= Time.deltaTime;  
                            if (TimerDown < 0) {  
                       TimerDown = 0;  
                       if (TimerDown == 0) {  
                       atk = true; // после окончания включаем возможность атаки     
                       TimerDown = Timer; // приводим таймер в дефолтное состояние     
                       }  
                            }  
                      }  
                }  
          }  
}


Всё! теперь мы можем рубить дерево не чаще чем каждую 1.7 долю-секунды . Далее займёмся начислением брёвен после срубки дерева .

Продолжаем!Займёмся рубкой уже поваленного дерева , начисления брёвен , а так же вывод данных на экран, поехали.
Дополним скрипт stat :

Код
using UnityEngine;  
using System.Collections;  

public class stat : MonoBehaviour {  
       public int volume = 5;  
       public int volumeBr = 5; // кол-во брёвен , содержащихся в дереве  
       public bool poval = false;  

       void Update () {  
       if (volume == 0) {  
             poval = true;  
             rigidbody.isKinematic = false;  
             rigidbody.AddRelativeForce(0, 0, 5);  

          }  
          if (volumeBr == 0) { // если брёвна закончились , дерево уничтожается      
                      DestroyObject (this.gameObject);  
                }  
       }  
}


Далее изменим AttackeWood :

Код
using UnityEngine;  
using System.Collections;  

public class AttackeWood : MonoBehaviour {  
       // Use this for initialization     
       public float Timer = 1.7f;  
       public int brevna = 0; //кол-во брёвен у нас     
       public float TimerDown; //сделал публичной для вывода на экран  
       public bool atk;  
       public int xp; // переменная для вывода на экран  

       void Start () {     
          Screen.showCursor = false;     
          TimerDown = Timer;  
          atk = true;  
       }     
           
       // Update is called once per frame     
       void Update () {     
                Ray ray = Camera.main.ScreenPointToRay (new Vector3 (Screen.width / 2, Screen.height / 2, 0));     
                RaycastHit hit;     
              
                if (Physics.Raycast (ray, out hit, 5f) && hit.collider.tag == "palm") {       
                      var to = hit.collider.GetComponent<stat> ();  
                          xp = to.volume; // вводим количество оставшихся ударов в переменную xp     
                      if (Input.GetMouseButtonUp (0) && to.poval == false && atk == true) {     
                            atk = false;  
                            to.volume -= 1;  
             }  
                         if (Input.GetMouseButtonUp (0) && to.poval == true && atk == true) { // если дерево повалено и мы  
//нажали ЛКМ и атака разрешена, то  
                     atk = false;  
                     to.volumeBr -= 1; // отбираем у дерева одно бревно     
                     brevna += 1; // и зачисляем нам  
                      }  
                }  
                if (atk == false) {  
                      if (TimerDown > 0) {  
                            TimerDown -= Time.deltaTime;  
                            if (TimerDown < 0) {  
                       TimerDown = 0;  
                       if (TimerDown == 0) {  
                       atk = true;  
                       TimerDown = Timer;  
                       }  
                            }  
                      }  
                }  
          }  
       void OnGUI () {  // Выводим данные на экран     
          GUI.Box(new Rect(100,20,200,40), "Кол-во брёвен : " + brevna);  
          GUI.Box(new Rect(100,70,200,40), "Перезарядка : " + TimerDown);  
          GUI.Box(new Rect(310,20,200,40), "Жизней у дерева : " + xp);  

          }  

}


Исходники: Скачать


Creator Assets-Unity3D
 
тин · OfflineДобавлено 14.10.2016 в 12:29 · Пост #2
http://forum.asterios.ws/

Добавлено (14.10.2016, 12:29)
---------------------------------------------
http://forum.asterios.ws/

Добавлено (14.10.2016, 12:29)
---------------------------------------------
http://forum.asterios.ws/

 
Форум » Unity3D » Уроки » Реализовываем рубку деревьев
  • Страница 1 из 1
  • 1
Поиск:

Все материалы опубликованные на сайте представлены исключительно для ознакомительного просьмота. Любое ваше несанкционированное использование "ассетов" в ваших коммерческих проектах карается уголовной ответственностью.
Хостинг от uCoz