Announcement

Collapse
No announcement yet.

kactor 구현 질문

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    kactor 구현 질문

    staticmesh를 포함하고있는 kactor와 skeletalmesh를 포함하고있는 kasset을 실습해봤습니다.


    UDK에는 Engine폴더의 staticmesh인 TextPropCube를 레벨에 AddRigidBody 하였습니다.
    나머지 하나인 kasset은 http://download.udk.com/tutorials/using-udk/3dbuzz_assets.zip 에서 받은 파일을 사용했습니다. package라는 파일안에 physics_asset.upk를
    UDKGame->content->3dbuzz(폴더생성) 에 집어넣고 UDK에서 fully load했습니다. 그렇게 표시된것중 SKM_Wire 를 새 피직스 애셋 생성했습니다.

    그렇게 새 피직스 생성한것을 레벨에 추가해줬습니다.

    이렇게 두 개의 kactor와 kasset을 레벨에 추가해놓고 이 두개를 클릭하면 정면이나 45도 각도로 날라가야합니다.

    (모바일 프리뷰어에서 실행합니다.)

    근데 아무리 클릭해도 날라가질 않습니다. 밑에는 이를 구현한 4개의 파일입니다.

    [exampleCh42Game.uc]
    Code:
    class exampleCh42Game extends FrameworkGame;
    
    event OnEngineHasLoaded(){
    	WorldInfo.Game.Broadcast(self,"exampleCh42Game Type Active-Enegine Has Loaded!!!");
    }
    
    function bool PreventDeath(Pawn KilledPawn, Controller Killer, class<DamageType> DamageType, vector HitLocation){
    	return true;
    }
    
    static event class<GameInfo> SetGameType(string MapName, string Options,string Portal){
    return super.SetGameType(MapName,Options,Portal);
    } 
    
     DefaultProperties
    {
    	PlayerControllerClass=class'exampleCh42.exampleCh42PC'
    	DefaultPawnClass=class'UDKBase.SimplePawn'
    	HUDType=class'UDKBase.UDKHUD'
    
    	bRestartLevel=false
    	bWaitingToStartMatch=true
    	bDelayedStart=false
    }
    [exampleCh42PC.uc]
    Code:
    class exampleCh42PC extends SimplePC;
    var float PickDistance;
    
    function ApplyForceRigidBody(Actor SelectedActor,Vector ImpulseDir,
    	float ImpulseMag,Vector HitLocation){
    	
    	if(SelectedActor.IsA('KActor')){
    		WorldInfo.Game.Broadcast(self,"***Thrown object"@SelectedActor@",ImpulseDir="@ImpulseDir@",ImpulseMag="@ImpulseMag@",HitLocation="@HitLocation);
    		SelectedActor(SelectedActor).ApplyImpulse(ImpulseDir,ImpulseMag,HitLocation);
    	}
    	else if(SelectedActor.IsA('KAsset')){
    		WorldInfo.Game.Broadcast(self,"***Thrown object"@SelectedActor@",ImpulseDir="@ImpulseDir@",ImpulseMag="@ImpulseMag@",HitLocation="@HitLocation);
    		SelectedActor(SelectedActor).SkeletalMeshComponent.
    			AddImpulse(ImpulseDir*ImpulseMag,,'Bone06');
    	}else{
    		WorldInfo.Game.Broadcast(self,"!!!ERROR Selected Actor"@SelectedActor@
    			"is not a Kactor,you can not apply an impulse to this object!!");
    	}
    }
    function Actor PickActor(Vector2D PickLocation,out Vector HitLocation,
    	out TraceHitInfo HitInfo){
    	local Vector TouchOrigin,TouchDir,HitNormal;
    	local Actor PickedActor;
    	local vector Extent;
    
    	PickLocation.X=PickLocation.X/ViewportSize.X;
    	PickLocation.Y=PickLocation.Y/ViewportSize.Y;
    
    	LocalPlayer(Player).Deproject(PickLocation,TouchOrigin,TouchDir);
    
    	Extent=vect(0,0,0);
    	PickedActor=Trace(HitLocation,HitNormal,TouchOrigin+(TouchDir*PickDistance),TouchOrigin
    		,True,Extent,HitInfo);
    
    	return PickedActor;
    }
    
    function bool SwipeZoneCallback(MobileInputZone Zone,float DeltaTime,int Handle,
    	ETouchType EventType,Vector2D TouchLocation){
    	local bool retval;
    
    	local Actor PickedActor;
    	local Vector HitLocation;
    	local TraceHitInfo HitInfo;
    
    	local Vector ImpulseDir;
    	local float ImpulseMag;
    
    	retval=true;
    
    	if(EventType==Touch_Began){
    		PickedActor=PickActor(TouchLocation,HitLocation,HitInfo);
    		WorldInfo.Game.Broadcast(self,"PickedAcotr="@PickedActor@",HitLocation="@HitLocation@",Zone Touched="@Zone);
    		ImpulseDir=Normal(Vector(Pawn.Rotation))+vect(0,0,1);
    		ImpulseMag=100;
    		ApplyForceRigidBody(PickedActor,ImpulseDir,ImpulseMag,HitLocation);
    	}else if(EventType==Touch_Moved){
    
    	}else if(EventType==Touch_Ended){
    
    	}
    	return retval;
    }
    
    function SetupZones(){
    	Super.SetupZones();
    
    	if(MPI!=None&&WorldInfo.GRI.GameClass!=none){
    		LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize);
    		if(FreeLookZone!=none){
    			FreeLookZone.OnProcessInputDelegate=SwipeZoneCallback;
    		}
    	}
    }
    
    defaultproperties{
    	PickDistance=10000;
    }
    [RigidBody.uc]
    Code:
    class RigidBody extends KActor;
    
    
    
    defaultproperties
    {
    	Begin Object Class=StaticMeshComponent Name=RigidBodyMesh
    		StaticMesh=StaticMesh'EditorMeshes.TexPropCube'
    		End Object
    	StaticMeshComponent=RigidBodyMesh
    	Components.Add(RigidBodyMesh)
    }
    [RopeSection.uc]
    Code:
    class RopeSection extends KAssetspawnable;
    
    
    
    defaultproperties
    {
    	Begin Object Class=SkeletalMeshComponent Name=RopeSection
    		SkeletalMesh=SkeletalMesh'physics_assets.SKM_Wire'
    		PhysicsAsset=PhysicsAsset'physics_assets.SKM_Wire_Physics'
    		End Object
    	SkeletalMeshComponent=RopeSection
    	Components.Add(RopeSection)
    }
    위의 코드대로 실행해보면

    event OnEngineHasLoaded(){
    WorldInfo.Game.Broadcast(self,"exampleCh42Game Type Active-Enegine Has Loaded!!!");
    }

    이 부분은 정상적으로 작동되지만 나머지 kactor와 kasset을 클릭할때는 무반응입니다.

    사실 RigidBody와 RopeSection 클래스는 혹시나해서 만든 파일입니다.

    kactor와 kasset을 구현하는데있어서 빼먹은 부분이나 잘못 코드를 작성한게있는건가요?

    #2
    [Initialize of Your KActor(e.g. After Spawn())]
    Code:
    SetPhysics(PHYS_falling);
    SetPhysics(PHYS_rigidbody);
    피직스를 추락 > 리짓 바디로 설정해서 물리 시뮬레이션을 깨우십시오.

    레벨에 배치한 경우, KActor.bWakeOnLevelStart를 참으로 설정하십시오.

    Comment


      #3




      액터와 에셋에 위의 이미지처럼 wake on level start 옵션을 줬습니다.

      이후 실행해보면 공중에 위치시킨 두개의 물체가 아래로 추락하면서 땅에 안정적으로 위치됐습니다.

      근데 모바일 프리뷰어로 실행해보니 해당 물체에 가해지는 힘은 전혀 없습니다.

      말씀하신걸로봐선 위의 코드에는 문제없다는것같은데 맞나요?

      Comment


        #4
        [Initialize of Your KActor(e.g. After Spawn() & Before ApplyImpulse())]
        Code:
        SetStaticMesh(StaticMesh'EditorMeshes.TexPropCube');
        컴포넌트를 직접 추가하지 말고 기존 메소드를 사용해 보십시오.

        Comment


          #5
          일단 구현을 위해서는 [exampleCh42Game.uc]파일과 [exampleCh42PC.uc]파일 이렇게 2개만 있으면 된다고합니다.(출처 책)

          여전히 문제는 물체에 마우스를 올려놓고 클릭을해도 충격을 안먹고 가만히 있는다는점과 Touch_Began이 됐으면 ApplyForceRigidBody함수가 호출되야하는데 아예 호출이 안돼는것같습니다. ApplyForceRigidBody함수의 디버그용으로 WorldInfo.Game.Broadcast로 메시지를 출력하게끔 해놨던것이 호출도 안됐었습니다.

          Comment


            #6
            그렇다면 엄한 곳을 짚었습니다.

            터치 콜백이 들어오는지 부터 확인하십시오.

            Code:
            SwipeZoneCallback()
            {
                  `log("SwipeZoneCallback called.");
            }
            SwipeZoneCallback() 함수 시작점에 로그를 배치하고 인수들을 출력해 보십시오.

            브로드캐스팅 또한 어떠한 조건에 의해 표시되지 않을 수 있으므로

            `log()를 사용하십시오.




            [add]

            지금 SimplePC 그리고 SetupZone()을 쓰고 계신데

            그 클래스와 함수는 언리얼의 기본 클래스, 함수가 아닙니다.

            따라서 에픽은 그 함수가 제대로 동작할 것이라는 것을 보장하지 않습니다.

            만약 SwipeZoneCallback()가 호출되고 있지 않다면

            그 라이브러리 제작자에게 문의하십시오.

            Comment


              #7
              2011년 6월 UDK 업데이트 내용
              "MobileGame, MobilePC, MobilePawn 클래스의 이름이 SimpleGame, SimplePC, SimplePawn 으로 각각 변경되었습니다." 라고 적혀있던데 이 세개의 클래스는 에픽이 공식으로 만들어서 배포한것이 아닌가요?

              그리고 이 문제는 잠시 보류하고 나중에 다시 해결해보도록하겠습니다. 답변주셔서 감사합니다.

              Comment


                #8
                UDKBase 패키지에 있는 것을 확인했습니다.

                보통 Engine 패키지를 쓰기 때문에 없는 것으로 착각했습니다.

                에픽 공식 배포 클래스, 함수가 맞습니다.

                Code:
                FreeLookZone.ActivateZone();
                을 추가해 보십시오.

                Comment


                  #9
                  안됩니다 swipezonecallback함수에 넣어봐도 SetupZone함수에 넣어봐도 안됩니다.

                  확실한 문제는 클릭했을때 브로드캐스팅 메시지만 남겨놔도 클릭후 뜨지않는 것으로봐서 SwipeZoneCallback메서드가 작동하지않는다는것입니다.

                  밑에는 SwipeZoneCallback메서드로 클릭이 성공적으로 적용된 예제입니다.

                  1인칭시점으로 바위형태의 총알을 쏘는 예제입니다.


                  [exampleCh3_2Game]
                  Code:
                  class exampleCh3_2Game extends FrameworkGame;
                  
                  event OnEngineHasLoaded(){
                  	WorldInfo.Game.Broadcast(self,"exampleCh3_2 Type Active-Enegine Has Loaded!!!");
                  }
                  
                  function bool PreventDeath(Pawn KilledPawn, Controller Killer, class<DamageType> DamageType, vector HitLocation){
                  	return true;
                  }
                  
                  static event class<GameInfo> SetGameType(string MapName, string Options,string Portal){
                  return super.SetGameType(MapName,Options,Portal);
                  }   
                  
                  DefaultProperties
                  {
                  	PlayerControllerClass=class'exampleCh3_2.exampleCh3_2PC'
                  	DefaultPawnClass=class'Jazz2Pawn'
                  	HUDType=class'UDKBase.UDKHUD'
                  
                  	bRestartLevel=false
                  	bWaitingToStartMatch=true
                  	bDelayedStart=false
                  }
                  [exampleCh3_2PC]
                  Code:
                  class exampleCh3_2PC extends simplePC;
                  
                  function bool SwipeZoneCallback(MobileInputZone Zone,float DeltaTime,int Handle,ETouchType EventType,Vector2D TouchLocation){
                  	local bool retval;
                  	retval=true;
                  
                  	if(EventType==Touch_Began){
                  		WorldInfo.Game.Broadcast(self,"You touched the screen at="@TouchLocation.x@","@TouchLocation.y@",Zone Touched="@Zone);
                  		//폰의 무기를 발사한다.
                  		StartFire(0);
                  	}else if(EventType==Touch_Moved){
                  		
                  	}else if(EventType==Touch_Ended){
                  		StopFire(0);
                  	}
                  	return retval;
                  }
                  
                  /*
                  //플레이어에게 직접 무기를 쥐어준다.
                  event Possess(Pawn aPawn, bool bVehicleTransition)
                  {
                  super.Possess(aPawn, bVehicleTransition);
                  aPawn.SetActiveWeapon(Spawn(class'JazzWeapon2'));
                  }
                  */
                  
                  function SetupZones(){
                  	Super.SetupZones();
                  
                  	if(MPI!=None&&WorldInfo.GRI.GameClass!=none){
                  		LocalPlayer(Player).ViewportClient.GetViewportSize(ViewportSize);
                  		if(FreeLookZone!=none){
                  			FreeLookZone.OnProcessInputDelegate=SwipeZoneCallback;
                  		}
                  	}
                  }
                  
                  
                  
                  function PlaceWeapon(){
                  	//1인칭
                  	local vector WeaponLocation;
                  	local Rotator WeaponRotation,TempRot;
                  	local Weapon TestW;
                  	local vector WeaponAimVect;
                  
                  	WeaponRotation.yaw=-16000;//90도 회전=오프셋
                  
                  	TempRot=Pawn.GetBaseAimRotation();
                  	WeaponRotation.pitch=TempRot.roll;
                  	WeaponRotation.yaw+=TempRot.yaw;
                  	WeaponRotation.roll-=TempRot.pitch;
                  	//무기의 로컬 축 방향으로 인해 방향을 전환시킨다.
                  
                  	WeaponAimVect=Normal(Vector(TempRot));
                  	WeaponLocation=Pawn.Location+(40*WeaponAimVect)+vect(0,0,30);
                  
                  	TestW=Pawn.Weapon;
                  
                  	if(TestW!=None){
                  		TestW.SetLocation(WeaponLocation);
                  		TestW.SetRotation(WeaponRotation);
                  	}else{
                  		WorldInfo.Game.Broadcast(self,"Player has no weapon!!!!!!");
                  	}
                  }
                  
                  function PlayerTick(float DeltaTIme){
                  	Super.PlayerTick(DeltaTime);
                  	PlaceWeapon();
                  }
                  
                  DefaultProperties
                  {
                  }
                  [jazz2Pawn]
                  Code:
                  class Jazz2Pawn extends SimplePawn;
                  
                  var Inventory MainGun;
                  
                  function AddDefaultInventory(){
                  	MainGun=InvManager.CreateInventory(class'JazzWeapon2');
                  
                  	MainGun.SetHidden(false);
                  
                  	Weapon(MainGun).FireOffset=vect(0,0,-70);
                  }
                  
                  DefaultProperties
                  {
                  	InventoryManagerClass=class'WeaponIM1'
                  }
                  [jazzBullet2]
                  Code:
                  class JazzBullet2 extends projectile;
                  
                  simulated function Explode(vector HitLocation,vector HitNormal){
                  	SetPhysics(Phys_Falling);
                  }
                  
                  function Init(Vector Direction){
                  	super.Init(Direction);
                  	RandSpin(90000);
                  }   
                  
                  DefaultProperties
                  {
                  	Begin Object Class=StaticMeshComponent Name=Bullet
                  		StaticMesh=StaticMesh'Castle_Assets.Meshes.SM_RiverRock_01'
                  		Scale3D=(X=0.3000000,Y=0.30000,Z=0.3000)
                  	End Object
                  	Components.Add(Bullet)
                  
                  	Begin Object Class=ParticleSystemComponent Name=BulletTrail
                  		Template=ParticleSystem'Castle_Assets.FX.P_FX_Fire_SubUV_01'
                  	End Object
                  	Components.Add(BulletTrail)
                  
                  	MaxSpeed=+05000.000000
                  	Speed=+05000.000000
                  }
                  [jazzWeapon2]
                  Code:
                  class JazzWeapon2 extends Weapon;
                  
                  DefaultProperties
                  {
                  	Begin Object Class=SkeletalMeshComponent Name=FirstPersonMesh
                  		SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun'
                  	End Object
                  	Mesh=FirstPersonMesh
                  	Components.Add(FirstPersonMesh);
                  
                  	Begin object Class=SkeletalMeshComponent Name=PickupMesh
                  		SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_JazzGun'
                  	End Object
                  	DroppedPickupMesh=PickupMesh
                  	PickupFactoryMesh=PickupMesh
                  
                  	WeaponFireTypes(0)=EWFT_Projectile
                  	WeaponFireTypes(1)=EWFT_NONE
                  
                  	WeaponProjectiles(0)=class'JazzBullet2'
                  	WeaponProjectiles(1)=class'JazzBullet2'
                  
                  	FiringStatesArray(0)=WeaponFiring
                  	FireInterval(0)=0.25
                  	Spread(0)=0
                  }
                  [WeaponIM1]
                  Code:
                  class WeaponIM1 extends InventoryManager;
                  
                  
                  DefaultProperties
                  {
                  	PendingFire(0)=0
                  	PendingFire(1)=0
                  }

                  Comment


                    #10
                    성공적으로 작동한 예시를 그대로 옮겼는데도 안된다는 것은

                    지금 제시하신 범위 밖에서 문제가 있을 확률이 높습니다.

                    우선은 콜 패스를 확실히 하실 필요가 있을 것 같습니다.

                    SetupZones()가 제대로 등록되는지 로깅하시고 제대로 셋업됨에도 콜백이 안된다면

                    어딘가 오탈자가 있거나 실수를 하셨을 가능성이 있습니다.

                    정상 작동한 예시와 면밀히 검토해 보십시오.

                    만약 아예 셋업도 호출이 되지 않는다면

                    컨트롤러나 게임 타입을 잘못 등록하셨을 수도 있습니다.

                    생성되는 컨트롤러의 이름(이름은 클래스이름_숫자로 할당됩니다.)도 찍어보시고

                    레벨의 월드 인포도 체크해 보시고

                    전박적으로 검토를 해보십시오.

                    Comment

                    Working...
                    X