По упомянутой просьбе на сайте решил немного поизучать вопрос переключения у игрока стандартного меша.
В играх, где есть несколько персонажей и необходимо переключаться между ними, или же на каждый уровень приходится свой персонаж, придется озаботится этим вопросом.
К делу. В итоге скопилось целых три способа(и скорее всего еще столько же можно придумать(найти)) и все как обычно: легкий,легкий и ... легкий. Начнем для разминки с легкого...
Здесь представлены только собственные классы SM_PlayerController, потому как основные добавления происходят в этих классах. Полные версии скриптов, готовые для компиляции находятся в архиве, который можно скачать по ссылке в конце статьи.
При этом не меняется сам класс Pawn, что пожалуй не есть гуд. Конечно можно напихать различных функций также переключающихся между собой, если какие-то свойства координально отличаются от старого персонажа...
Для примера создал спец блок для кисмета, при срабатывании которого и будет происходить, столь вожделенные события. Напомню, что все на достаточно примитивном уровне, без изысков и спецэффектов - быстрая спартанская смена меша. При достаточной сноровке переходный процесс можно или спрятать или скрасить. Конечно же можно назначить смену pawn на какую нибудь кнопку, действие и т.д. алгоритм в целом не поменяется.
класс SM_PlayerController:
В играх, где есть несколько персонажей и необходимо переключаться между ними, или же на каждый уровень приходится свой персонаж, придется озаботится этим вопросом.
К делу. В итоге скопилось целых три способа(и скорее всего еще столько же можно придумать(найти)) и все как обычно: легкий,легкий и ... легкий. Начнем для разминки с легкого...
Здесь представлены только собственные классы SM_PlayerController, потому как основные добавления происходят в этих классах. Полные версии скриптов, готовые для компиляции находятся в архиве, который можно скачать по ссылке в конце статьи.
Простая замена меша игрока во время игры.
Суть заключается в том, что у игрока по триггеру заменяется меш, материал, анимсэты, и анимтемплейт. Причем, если между старым и новым видом разница только в самом меше и материалах(т.е. анимация и анимтемплейт у них одинаковы),значит нужно будет просто заменить сам меш и материалы.При этом не меняется сам класс Pawn, что пожалуй не есть гуд. Конечно можно напихать различных функций также переключающихся между собой, если какие-то свойства координально отличаются от старого персонажа...
Для примера создал спец блок для кисмета, при срабатывании которого и будет происходить, столь вожделенные события. Напомню, что все на достаточно примитивном уровне, без изысков и спецэффектов - быстрая спартанская смена меша. При достаточной сноровке переходный процесс можно или спрятать или скрасить. Конечно же можно назначить смену pawn на какую нибудь кнопку, действие и т.д. алгоритм в целом не поменяется.
класс SM_PlayerController:
class SM_PlayerController extends GamePlayerController; var SkeletalMesh Changemesh; var MaterialInterface ChangeMaterial0; var AnimTree ChangeAnimTree; var array<animset> ChangeAnimSet; var AnimNodeSequence ChangeAnimSeq; var PhysicsAsset ChangePhysicsAsset; var bool SwitchMesh; simulated event PostBeginPlay() { super.PostBeginPlay(); //`log("SM_PlayerController"); } // вызывается из кисмета и поменяет перса. function SwitchPerson(bool Allowed) { SwitchMesh = Allowed; if(SwitchMesh) { SwitchMesh = FALSE // Сначала прописываем на какой именно меш будем менять, для примера взять // стандартный меш IronGuard ChangeMesh=SkeletalMesh'CH_IronGuard_Male.Mes h.SK_CH_IronGuard_MaleA' ChangeAnimTree=AnimTree'CH_AnimHuman_Tree.AT_ CH_Human'; ChangeAnimSet[0]=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_AimOffset'; ChangeAnimSet[1]=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'; ChangePhysicsAsset=PhysicsAsset'CH_AnimCorrup t.Mesh.SK_CH_Corrupt_Male_Physics'; // Затем поочередно применяем self.Pawn.Mesh.SetSkeletalMesh(ChangeMesh); self.Pawn.Mesh.SetMaterial(0,MaterialInstanceConstant'CH_IronGuard_Male.Materials.MI_CH_IronG_MHead01_V01'); self.Pawn.Mesh.SetMaterial(1,MaterialInstanceConstant'CH_IronGuard_Male.Materials.MI_CH_IronG_Mbody01_V01'); /* !! Понадобится если будете менять на перса у которого другая анимация и физика */ //self.Pawn.Mesh.SetPhysicsAsset(ChangePhysicsAsset); //self.Pawn.Mesh.AnimSets=ChangeAnimSet; //self.Pawn.Mesh.SetAnimTreeTemplate(ChangeAnimTree); } } defaultproperties { SwitchMesh = FALSE }
Полная замена pawn на другой, только что вызванный.
Принцип в этот раз несколько другой. По пунктам: отключаем pawn от контроллера игрока - удаляем его - вызываем новый pawn - подключаем к нему контроллер игрока. Здесь сделано так же, так что это дело происходит по спец. блоку из кисмета, например, по триггеру.класс SM2_PlayerController:
class SM2_PlayerController extends GamePlayerController var bool SwitchPawn; simulated event PostBeginPlay() { super.PostBeginPlay(); //`log("SM2_PlayerController"); } // вызывается из кисмета и поменяет перса. function SwitchPerson(bool Allowed) { Local Pawn ReserveBeef; Local vector Loc; SwitchPawn = Allowed; if(SwitchPawn) { SwitchPawn = FALSE; //Запоминаем текущий pawn ReserveBeef = Pawn; // Запоминаем его расположение Loc = Pawn.Location; // отсоединяем текущий pawn UnPossess(); // Уничтожаем отсоединенный pawn ReserveBeef.Destroy(); //Вызываем новый pawn ReserveBeef = Spawn(class'SM2_AnotherPawn', ,, Loc + vect(50,0,50)); // Присоединяем новый pawn Possess(ReserveBeef,false); } } defaultproperties { SwitchPawn = FALSE }
Переключение между двумя различными pawn
На уровне появляются сразу два меша, один под котролем AI. По спец блоку из кисмета происходит обмен между ними мешами - переключение котроллеров.По принципу этот способ такой же как и предыдущий. Его пункты таковы: отключаем меши от контроллеров - переназначаем котроллеры другим мешам.
класс SM3_PlayerController:
class SM3_PlayerController extends GamePlayerController; var bool SwitchPawn; var Pawn ReserveBeef; simulated event PostBeginPlay() { // Вызываем другой pawn, по умолсчанию он под AI Controller ReserveBeef = Spawn(Class'SM3_AnotherPawn',,, Location - vect(100,0,0) , Rotation); super.PostBeginPlay(); } // Вызывается из кисмета и говорит что можно поменять перса. function SwitchPerson(bool Allowed) { Local Controller Cont; Local Pawn OldPawn; SwitchPawn = Allowed; if(SwitchPawn == TRUE) { SwitchPawn = FALSE; //Запоминаем текущий pawn OldPawn = Pawn; //Запоминаем AI Controller того pawn куда переселимся Cont = ReserveBeef.Controller; //Отсоединяем наш старый pawn UnPossess(); //Отсоединяем новый pawn от AI Controller Cont.UnPossess(); //Присоединяемся Possess(ReserveBeef, false); //Старый pawn ставим под контроль AI Controller Cont.Possess(OldPawn, false); } } defaultproperties { SwitchPawn = FALSE }
Результат на видео:
Все три способа можно неплохо довести до ума, например сделать взаимно обратной переключения по клавише между двумя героями. Так что все в ваши руках.
PS. Все делалось в мартовской версии UDK(2011).
No comments:
Post a Comment