hướng dẫn camera 3D 100% của RPG
Trang 1 trong tổng số 1 trang
hướng dẫn camera 3D 100% của RPG
Bây giờ mình sẽ chỉ các bạn một camera 3D có thể xoay quanh nhân vật 100% bằng right_click. Tuy nhiên mình vẫn còn khá nhiều điều không hợp lý và hy vọng ai làm tutorial này nếu có thể chỉnh sửa cùng góp ý với mình thì rất cảm ơn. Cuối bài mình sẽ nêu những điều mình còn chưa hài lòng sau.
- Đầu tiên là phần chuẩn bị: Ở đây mình cần 4 file, các bạn đã biết cách tạo file UnrealScript rồi thì mình sẽ không nói lại phần ấy. 4 file đó là: main, MyPawn, MyCamera, MyGamePlayerController. Các bạn có thể đặt tên khác nhau thì tùy miễn các bạn biết các bạn đặt làm gì.
+ Với file MyPawn các bạn chỉnh extends đến Pawn
class MyPawn extends GamePawn;
Tương tự: MyCamera: các bạn extends đến Camera; MyGamePlayerController: các bạn extends đến GamePlayerController ; main thì là GameInfo
+Ở đây mình sẽ giải thích 1 tí, các bạn đừng nhầm UnrealScript chỉ sử dụng trên ngôn ngữ C/C++, ở đây nó còn sử dụng cả Java, bằng chứng là nó sử dụng Extends để mở rộng đến các classes khác, mỗi class con chỉ được extends đến 1 class cha thôi và như bạn biết nó sẽ có thể sử dụng những gì mà class cha đã build sẵn, tất nhiên không phải cái gì build sẵn ở class cha cũng xài được mà đôi khi ta cần phải viết lại hàm đó. Lát nữa phần dưới các bạn sẽ gặp vấn đề như thế.
+ 1 điều nữa là công cụ sẽ rất đắc lực với bạn trong đây là Search ( Ctrl+shift+F ), tôi nghĩ các bạn nên làm quen đi, vì các hàm trong Unreal con số có thể lên tới 300 hàm và nhiều biến nhỏ chưa tính đấy. Bạn ko thể nào ngồi mà tìm từng dòng đâu. Thay vào đó là Search hoặc với 1 hàm hoặc biến mà các bạn trong khi nghiên cứu code của người khác mà ko biết nó nằm chỗ nào, hãy double_click lên hàm ( biến ), sau đó right_click >>> " Go To Definition ", bạn sẽ biết hàm đó ( biến ) nó định nghĩa ở đâu.
-Cơ bản các file chúng ta đã có, giờ chúng ta sẽ vào từng file để thêm code. Bắt đầu sẽ là MyGamePlayerController
class MyGamePlayerController extends GamePlayerController;
+ 'Log ("I am Alive)") ở đây chỉ thêm để check coi Class MyGamePlayerController có hoạt động hay ko, nếu hoạt động thì trong bảng Log ( nếu các bạn để ý khi cài đặt nfringe ở tab Debug tôi có kêu check mục " Open Log at Position" >>> nó sẽ hiện 1 bảng log đen khi chạy debug ) sẽ hiện chữ "Script Log: Iam Alive " >>> Class hoạt động tốt đấy.
+Như tôi đã nói ở trên, không phải lúc nào Class cha cũng đáp ứng các nhu cầu của Class con, như tôi muốn xuất 'Log ngay khi game vừa chạy, tôi không muốn phải vào Class cha GamePlayerController để sửa ( để ý Class này đã bị khóa bởi ReadOnly, cái này nhằm tránh cho chúng ta sửa kẻo hư luôn toàn bộ code ). Vậy làm sao để sửa, Simulated sẽ giúp chúng ta điều đó, nó sẽ nói rằng, chúng ta viết ngược lại event PostBeginPlay( ) >>> giờ thì hệ thống sẽ không dùng PostBeginPlay( ) trong Class Cha GamePlayerController nữa mà sẽ dùng ở Class con MyGamePlayerController. Có những trường hợp Class Cha hoàn toàn xài được nhưng vẫn thiếu 1 số cái ta cần, nghĩa là ta có thể sử dụng lại toàn bộ code trong hàm đó mà ko cần sửa gì cả, chủ yếu là ta cần thêm váo 1 số code của riêng ta ( ko đụng tới code hàm cha ), lúc ấy hãy dùng Super.Function . Super sẽ nói, ta muốn sử dụng lại toàn bộ code trong hàm PostBeginPlay () trong Class Cha >>> khỏi phải viết lại.
+ exec giống như hàm chạy, tôi cũng ko biết nói thế nào cho rõ ý nghĩa của nó, hy vọng có ai đó sẽ giúp tôi trong việc dịch ý nghĩa của các biến và class build sẵn trong UnrealScript (http://udn.epicgames.com/Three/UnrealScriptReference.html). ZoomCameraIn ,ZoomCameraOut, Free, NonFree tương ứng với MouseScrollUp, MouseScrollDown, Right_click, và khi thả Right_Click ( Release Right_Click ). Các biến này sẽ được định nghĩa trong thư mục UDKGame/Config/UDKInput.ini . Trong đây nó sẽ định nghĩa các phím, chuột,button gamepad. Các bạn thêm vào cuối [Engine.PlayerInput]
+ OK, ở defaultPropertise các bạn thấy có CameraClass=Class'UDKProject.MyCamera' >>> vì theo hệ thống Unreal, Camera được định nghĩa trong Class PlayerController ( các bạn có thể Search"CameraClass" và tìm ở file PlayerController các bạn sẽ thấy các liên quan để CameraClass ), nhưng ở đây ta ko cùng Class Camera mà ta sẽ dùng Class MyCamera của chúng ta nên chúng ta phải default lại Propertise.
+MyGamePlayerController giống như là nơi tập trung các vấn đề về điều khiển nhân vật, điều khiển hệ thống, để tìm hiểu thêm các bạn có thể vào file PlayerController để xem nó defaul cái gì và nó viết những hàm gì, hy vọng sẽ giúp các bạn hiểu ý tôi nói.
-Còn bây giờ là tới MyCamera.
-Thêm các code sau vào MyPawn:
Chúng ta đã xong tutorial rồi đấy, giờ tôi sẽ nói những điểm tôi chưa hài lòng, thứ nhất khi xoay camera = right_click, nó xoay tốt đấy, nhưng khi release nó ko update lại hướng mà camera tôi thả ra,.... nó xoay về cái hướng con robot đang nhìn. Tôi chưa code Movement nên có thể vì thế mà kết quả chưa như ý. đặc biệt khi bạn di chuyển bạn sẽ thấy. Tôi hy vọng có thể tìm một team nào đó nghiên cứu code UnrealScript vì nói thật một mình tôi ko thể nghiên cứu hết được những gì bất cập hiện này.
- Đầu tiên là phần chuẩn bị: Ở đây mình cần 4 file, các bạn đã biết cách tạo file UnrealScript rồi thì mình sẽ không nói lại phần ấy. 4 file đó là: main, MyPawn, MyCamera, MyGamePlayerController. Các bạn có thể đặt tên khác nhau thì tùy miễn các bạn biết các bạn đặt làm gì.
+ Với file MyPawn các bạn chỉnh extends đến Pawn
class MyPawn extends GamePawn;
Tương tự: MyCamera: các bạn extends đến Camera; MyGamePlayerController: các bạn extends đến GamePlayerController ; main thì là GameInfo
+Ở đây mình sẽ giải thích 1 tí, các bạn đừng nhầm UnrealScript chỉ sử dụng trên ngôn ngữ C/C++, ở đây nó còn sử dụng cả Java, bằng chứng là nó sử dụng Extends để mở rộng đến các classes khác, mỗi class con chỉ được extends đến 1 class cha thôi và như bạn biết nó sẽ có thể sử dụng những gì mà class cha đã build sẵn, tất nhiên không phải cái gì build sẵn ở class cha cũng xài được mà đôi khi ta cần phải viết lại hàm đó. Lát nữa phần dưới các bạn sẽ gặp vấn đề như thế.
+ 1 điều nữa là công cụ sẽ rất đắc lực với bạn trong đây là Search ( Ctrl+shift+F ), tôi nghĩ các bạn nên làm quen đi, vì các hàm trong Unreal con số có thể lên tới 300 hàm và nhiều biến nhỏ chưa tính đấy. Bạn ko thể nào ngồi mà tìm từng dòng đâu. Thay vào đó là Search hoặc với 1 hàm hoặc biến mà các bạn trong khi nghiên cứu code của người khác mà ko biết nó nằm chỗ nào, hãy double_click lên hàm ( biến ), sau đó right_click >>> " Go To Definition ", bạn sẽ biết hàm đó ( biến ) nó định nghĩa ở đâu.
-Cơ bản các file chúng ta đã có, giờ chúng ta sẽ vào từng file để thêm code. Bắt đầu sẽ là MyGamePlayerController
class MyGamePlayerController extends GamePlayerController;
- Code:
class MyGamePlayerController extends GamePlayerController;
simulated event PostBeginPlay()
{
super.PostBeginPlay();
`Log("I am alive !");
}
exec function ZoomCameraIn()
{
if(PlayerCamera.FreeCamDistance >=100 )
PlayerCamera.FreeCamDistance -=10;
}
exec function ZoomCameraOut()
{
if(PlayerCamera.FreeCamDistance <=170)
PlayerCamera.FreeCamDistance +=10;
}
exec function Free()
{
MyCamera(PlayerCamera).BeginFreeLook();
}
exec function NonFree()
{
MyCamera(PlayerCamera).StopFreeLook();
}
DefaultProperties
{
CameraClass=class'UDKProject.MyCamera'
}
+ 'Log ("I am Alive)") ở đây chỉ thêm để check coi Class MyGamePlayerController có hoạt động hay ko, nếu hoạt động thì trong bảng Log ( nếu các bạn để ý khi cài đặt nfringe ở tab Debug tôi có kêu check mục " Open Log at Position" >>> nó sẽ hiện 1 bảng log đen khi chạy debug ) sẽ hiện chữ "Script Log: Iam Alive " >>> Class hoạt động tốt đấy.
+Như tôi đã nói ở trên, không phải lúc nào Class cha cũng đáp ứng các nhu cầu của Class con, như tôi muốn xuất 'Log ngay khi game vừa chạy, tôi không muốn phải vào Class cha GamePlayerController để sửa ( để ý Class này đã bị khóa bởi ReadOnly, cái này nhằm tránh cho chúng ta sửa kẻo hư luôn toàn bộ code ). Vậy làm sao để sửa, Simulated sẽ giúp chúng ta điều đó, nó sẽ nói rằng, chúng ta viết ngược lại event PostBeginPlay( ) >>> giờ thì hệ thống sẽ không dùng PostBeginPlay( ) trong Class Cha GamePlayerController nữa mà sẽ dùng ở Class con MyGamePlayerController. Có những trường hợp Class Cha hoàn toàn xài được nhưng vẫn thiếu 1 số cái ta cần, nghĩa là ta có thể sử dụng lại toàn bộ code trong hàm đó mà ko cần sửa gì cả, chủ yếu là ta cần thêm váo 1 số code của riêng ta ( ko đụng tới code hàm cha ), lúc ấy hãy dùng Super.Function . Super sẽ nói, ta muốn sử dụng lại toàn bộ code trong hàm PostBeginPlay () trong Class Cha >>> khỏi phải viết lại.
+ exec giống như hàm chạy, tôi cũng ko biết nói thế nào cho rõ ý nghĩa của nó, hy vọng có ai đó sẽ giúp tôi trong việc dịch ý nghĩa của các biến và class build sẵn trong UnrealScript (http://udn.epicgames.com/Three/UnrealScriptReference.html). ZoomCameraIn ,ZoomCameraOut, Free, NonFree tương ứng với MouseScrollUp, MouseScrollDown, Right_click, và khi thả Right_Click ( Release Right_Click ). Các biến này sẽ được định nghĩa trong thư mục UDKGame/Config/UDKInput.ini . Trong đây nó sẽ định nghĩa các phím, chuột,button gamepad. Các bạn thêm vào cuối [Engine.PlayerInput]
- Code:
Bindings=(Name="RightMouseButton",Command="Free | OnRelease NonFree")
Bindings=(Name="MouseScrollUp",Command="ZoomCameraIn")
Bindings=(Name="MouseScrollDown",Command="ZoomCameraOut")
+ OK, ở defaultPropertise các bạn thấy có CameraClass=Class'UDKProject.MyCamera' >>> vì theo hệ thống Unreal, Camera được định nghĩa trong Class PlayerController ( các bạn có thể Search"CameraClass" và tìm ở file PlayerController các bạn sẽ thấy các liên quan để CameraClass ), nhưng ở đây ta ko cùng Class Camera mà ta sẽ dùng Class MyCamera của chúng ta nên chúng ta phải default lại Propertise.
+MyGamePlayerController giống như là nơi tập trung các vấn đề về điều khiển nhân vật, điều khiển hệ thống, để tìm hiểu thêm các bạn có thể vào file PlayerController để xem nó defaul cái gì và nó viết những hàm gì, hy vọng sẽ giúp các bạn hiểu ý tôi nói.
-Còn bây giờ là tới MyCamera.
- Code:
class MyCamera extends Camera;
var bool bFreeLookMode;
var bool batdau;
simulated function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
{
local vector Loc, Pos, HitLocation, HitNormal;
local rotator Rot;
local Actor HitActor;
local CameraActor CamActor;
local bool bDoNotApplyModifiers;
local TPOV OrigPOV;
// store previous POV, in case we need it later
OrigPOV = OutVT.POV;
// Default FOV on viewtarget
OutVT.POV.FOV = DefaultFOV;
// Viewing through a camera actor.
CamActor = CameraActor(OutVT.Target);
if( CamActor != None )
{
CamActor.GetCameraView(DeltaTime, OutVT.POV);
// Grab aspect ratio from the CameraActor.
bConstrainAspectRatio = bConstrainAspectRatio || CamActor.bConstrainAspectRatio;
OutVT.AspectRatio = CamActor.AspectRatio;
// See if the CameraActor wants to override the PostProcess settings used.
CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha;
CamPostProcessSettings = CamActor.CamOverridePostProcess;
}
else
{
// Give Pawn Viewtarget a chance to dictate the camera position.
// If Pawn doesn't override the camera view, then we proceed with our own defaults
if( Pawn(OutVT.Target) == None ||
!Pawn(OutVT.Target).CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) )
{
// don't apply modifiers when using these debug camera modes.
bDoNotApplyModifiers = TRUE;
if(!batdau)
{
FreeCamDistance=50;
}
batdau=true;
switch( CameraStyle )
{
case 'Fixed' : // do not update, keep previous camera position by restoring
// saved POV, in case CalcCamera changes it but still returns false
OutVT.POV = OrigPOV;
break;
case 'ThirdPerson' : // Simple third person view implementation
case 'FreeCam' :
case 'FreeCam_Default':
Loc = OutVT.Target.Location;
Rot = OutVT.Target.Rotation;
http://OutVT.Target.GetActorEyesViewPoint(Loc, Rot);
if( CameraStyle == 'FreeCam' || CameraStyle == 'FreeCam_Default' )
{
Rot = PCOwner.Rotation;
}
Loc += FreeCamOffset >> Rot;
Pos = Loc - Vector(Rot) * FreeCamDistance;
// @fixme, respect BlockingVolume.bBlockCamera=false
HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12));
OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation;
OutVT.POV.Rotation = Rot;
break;
case 'Isometric':
Loc = OutVT.Target.Location;
if(CameraStyle=='Isometric' && bFreeLookMode == true)
{
Rot = PCOwner.Rotation;
}
Loc += FreeCamOffset >> Rot;
Pos = Loc - Vector(Rot) * FreeCamDistance;
HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12));
OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation;
OutVT.POV.Rotation = Rot;
break;
case 'FirstPerson' : // Simple first person, view through viewtarget's 'eyes'
default : OutVT.Target.GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation);
break;
}
}
}
if( !bDoNotApplyModifiers )
{
// Apply camera modifiers at the end (view shakes for example)
ApplyCameraModifiers(DeltaTime, OutVT.POV);
}
//`log( WorldInfo.TimeSeconds @ GetFuncName() @ OutVT.Target @ OutVT.POV.Location @ OutVT.POV.Rotation @ OutVT.POV.FOV );
}
function BeginFreeLook()
{
`Log("Press");
http://Controller.SetRotation(Rotation);
bFreeLookMode = true;
}
function StopFreeLook()
{
bFreeLookMode = false;
}
DefaultProperties
{
DefaultFOV=90.f //Zoom ( giong nhu aim )
bFreeLookMode=false
}
-Thêm các code sau vào MyPawn:
- Code:
class MyPawn extends GamePawn;
var bool bFreeLookMode;
simulated function name GetDefaultCameraMode( PlayerController RequestedBy )
{
return 'Isometric';
//return 'FreeCam';
//return 'FreeCam_Default';
//return 'ThirdPerson';
}
simulated event bool InFreeCam()
{
local PlayerController PC;
PC = PlayerController(Controller);
return (PC != None && PC.PlayerCamera != None && (PC.PlayerCamera.CameraStyle == 'FreeCam' || PC.PlayerCamera.CameraStyle == 'FreeCam_Default'||PC.PlayerCamera.CameraStyle == 'Isometric') );
}
DefaultProperties
{
Components.Remove(Sprite)
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
ModShadowFadeoutTime=0.25
MinTimeBetweenFullUpdates=0.2
AmbientGlow=(R=.01,G=.01,B=.01,A=1)
AmbientShadowColor=(R=0.15,G=0.15,B=0.15)
LightShadowMode=LightShadow_ModulateBetter
ShadowFilterQuality=SFQ_High
bSynthesizeSHLight=TRUE
End Object
Components.Add(MyLightEnvironment)
Begin Object Class=SkeletalMeshComponent Name=InitialSkeletalMesh
CastShadow=true
bCastDynamicShadow=true
bOwnerNoSee=false
LightEnvironment=MyLightEnvironment;
BlockRigidBody=true;
CollideActors=true;
BlockZeroExtent=true;
PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics'
AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_AimOffset'
AnimSets(1)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
SkeletalMesh=SkeletalMesh'CH_LIAM_Cathode.Mesh.SK_CH_LIAM_Cathode'
End Object
Mesh=InitialSkeletalMesh;
Components.Add(InitialSkeletalMesh);
}
Chúng ta đã xong tutorial rồi đấy, giờ tôi sẽ nói những điểm tôi chưa hài lòng, thứ nhất khi xoay camera = right_click, nó xoay tốt đấy, nhưng khi release nó ko update lại hướng mà camera tôi thả ra,.... nó xoay về cái hướng con robot đang nhìn. Tôi chưa code Movement nên có thể vì thế mà kết quả chưa như ý. đặc biệt khi bạn di chuyển bạn sẽ thấy. Tôi hy vọng có thể tìm một team nào đó nghiên cứu code UnrealScript vì nói thật một mình tôi ko thể nghiên cứu hết được những gì bất cập hiện này.
honglong99- Tổng số bài gửi : 24
Join date : 08/07/2010
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết
|
|