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 и теперь она будет падать "по любому" от одного удара. Вскоре я обновлю тему , сделаю счётчик ударов для каждой пальмы (чтобы не ломалась после одного удара ) сделаю деревьям пеньки , которые будут оставаться после срубки и мини инвентарь , который показывает число нарубленных брёвен (начисляться будут после ударов уже поваленного дерева и после нного кол-ва ударов дерево будет исчезать), реализация самого топора со звуками при ударе о дерево и анимацией.Вот такой несложный урок получился , спасибо за то что прочли , оставляйте отзывы и пишите чего бы вы хотели увидеть .
Продолжаем ! Сейчас мы реализуем накопительную систему для каждого дерева ,чтобы только после определённого кол-ва ударов оно упало.Для этого откроем наш прошлый скрипт с 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 ударов дерево упадёт, далее займёмся системой пауз между ударов , чтобы их(удары) можно было наносить только спустя пару секунд.Оценивайте
Привет! Реализуем паузы между ударами. Возьмём всё тот же скрипт 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/
|
|
| |