# ratrace135

Members

18

447 Neutral

• Rank
Member
1. ## Book/tutorials for 3d game programming c++

If you only have a basic knowledge of C, I would work on expanding your general knowledge before cracking down on graphics or other more specific programming.   I started off C++ with http://www.amazon.com/Beginning-C-Through-Game-Programming/dp/1435457420 which, despite the title, is very much a general C++ book simply taught from the perspective of games. If you don't want to get a book, http://www.learncpp.com/ is a great site for C++ tutorials. While you would eventually need to learn to work with either DirectX or OpenGL (or both) to build your own engine, I wouldn't recommend doing so without having solid fundamentals. If you're solid on all, or at least most, of the topics on learncpp.com, then I'd say you're ready to move on.
2. ## Smooth camera movements/rotations (conversion between eye&up vector and quaternions)

Hey taytay, I'd recommend reading this tutorial: http://ogldev.atspace.co.uk/www/tutorial15/tutorial15.html The site itself has OpenGL tutorials, but the concepts in this tutorial are universal and would easily work with whatever you're using.   Basically, quaternions allow you to rotate around any axis you want, as opposed to strictly the x, y, or z axes. While the typical first-person camera rotates left and right around a fixed axis (the y-axis), vertical camera rotation happens around the cross product of the y-axis and the target vector, which is not fixed. So what you want isn't to convert between vectors and quaternions, but rather to use quaternions to rotate vectors. The tutorial above doesn't go too deep into the math involved, but it shows how you would go about doing this in a practical sense.   And yes, quaternions can be interpolated (spherical linear interpolation, or slerp, is used often in 3D animation). However, slerping (any interpolation, really) only works when you have two points--a start and an end--and you want to move between the two. Slerping isn't used to figure out where the end point should be.   Hope this helps!

4. ## [Update 8pm GMT] UDK: Model's animations aren't playing!

If it were one thing, I'd guess it's the AnimNodeSequence object in the DefaultProperties. UTPawn already has two AnimNodeSequences called MeshSequenceA and MeshSequenceB, so trying to overwrite MeshSequenceA might be causing the problem. Try commenting out those two lines in your pawn's DefaultProperties (right above the commented-out DynamicLightEnvironment) and see if that helps.   Failing that, there's always the obligatory "make sure the animation actually works in the editor" advice. :P   Also, I've heard that DefaultProperties doesn't like spaces with declarations, like "BirdWalkAnim = WalkOnLand"... Apparently it's better to write "BirdWalkAnim=WalkOnLand". I've personally never had any problem with it either way, but can't hurt to try, even though it's probably not the source of the problem.   Hope something here works for you :D
5. ## [Update 8pm GMT] UDK: Model's animations aren't playing!

Glad to hear that the collision cylinder's aligned now   As for animations, the PlayAnim function takes a name as the first parameter, not an AnimSet (which is what I assume you're trying to call with that line). If the anim name you want to play is WalkOnLand, then assuming that you have BirdWalkAnim set in the DefaultProperties, you'd use the line: Pawn.Mesh.PlayAnim( BirdPawn(Pawn).BirdWalkAnim, , True );   There's no need to mess with the file path OR anim set with the PlayAnim function, which will search the SkeletalMeshComponent's AnimSets array to find the correct animation.
6. ## [Update 8pm GMT] UDK: Model's animations aren't playing!

Yeah, that's super common. Characters smaller than bullets and guns bigger than buildings. :P   I'd just place the model in a level and scale it however much you need it to be in UDK. Take note of how much you scaled it, then go into blender or any other modeling tool, scale it to that size in there, and reimport. A trick to help with that is to have your (correctly-scaled) character model in the scene when you're modeling, to use as a reference for scale.   But yeah, definitely correct the scale in your modelling tool and reimport... Dealing with a bunch of models out of scale is way more of a headache than it's worth.
7. ## [Update 8pm GMT] UDK: Model's animations aren't playing!

Ahh yes. For the pawn mesh, if you're extending from both UTPawn and UTBot, you have to deal with UTFamilyInfo... There are two things you can do. One would be to extend your own class from UTFamilyInfo and set that as the CurrCharClassInfo in your pawn. The other choice would be to overwrite the family info function in your pawn if you don't want to deal with family info at all, like simulated function SetCharacterClassFromInfo(class<UTFamilyInfo> Info) { //Ignoring family info }   As for animations, I can't see if you're calling any animations. The typical way of getting the pawn to start playing animations is to, in the controller/bot class, set the player's physics to PHYS_Falling by calling Pawn.SetMovementPhysics() when the controller class has possessed a pawn (which has already been done in UTBot). However, that only gets animations playing because of the animtree. So if you wanted to play an idle animation on startup for example, you'd need to directly call the animation. //We're in the bot class function Possess( Pawn aPawn, bool bVehicleTransition ) { super.Possess( aPawn, bVehicleTransition ); aPawn.Mesh.PlayAnim( BirdPawn(aPawn).IdleAnim, , True ); //Loops a hypothetical IdleAnim }   Finally, for the player hovering above the ground, that would most likely be that the collision cylinder and the mesh aren't aligned. Play the level and in the console, type "show collision". What you'll probably see is the collision cylinder touching the ground and the mesh hovering somewhere above that. To fix that, you'll need to modify the WPawnSkeletalMeshComponent's Z Translation in the DefaultProperties. UTPawn has it set to 8, but you'll have to change that number to work for your mesh, depending on where its pivot point is.
8. ## [Update 8pm GMT] UDK: Model's animations aren't playing!

The problem would be that you're using a SkeletalMeshComponent in the SetSkeletalMesh function, which takes a SkeletalMesh (sorry if I didn't make that clear in my post).   But if you have the component added in the DefaultProperties (like you have it), there's no need to dynamically attach it again. Dynamic attachment is meant for cases when you can't have the attachment in the DefaultProperties because you don't know what it will be (such as armor pieces for a pawn, weapon add-ons, etc).   Also, for some reason I was under the impression you were extending from a class below UTPawn... UTPawn has the WPawnSkeletalMeshComponent, whose settings you can change pretty quickly to get a visible body mesh. UTPawn also already has a DynamicLightEnvironment and two AnimNodeSequences (for the arms meshes, but we can steal them for the body mesh if you aren't using an anim tree ). The "Mesh" variable from the Pawn class is also referenced to WPawnSkeletalMeshComponent, so you can use that in your code. This will be enough to give your pawn a mesh that's capable of playing animations: class BirdPawn extends UTPawn; var name BirdWalkAnim; simulated function PostBeginPlay() { super.PostBeginPlay(); SetMeshVisibility(true); `log("The player birdpawn has spawned!"); } defaultproperties { Begin Object Name=WPawnSkeletalMeshComponent SkeletalMesh=SkeletalMesh'BirdPackage.BooboodayPacked' AnimSets(0)=AnimSet'BirdPackage.Armature' Animations=MeshSequenceA AnimTreeTemplate=None Materials(0)=Material'EditorMaterials.WidgetMaterial_X' LightEnvironment=MyLightEnvironment Scale3D=(X=0.25,Y=0.25,Z=0.5) End Object BirdWalkAnim = WalkOnLand } Depending on the scope of your project, it may be worth it to spend the time making an animtree. They're a pain to make, but they make it very easy to change or blend animations based on pawn physics, looking direction, etc.
9. ## Dynamic Arrays in UnrealScript...

Well... usually you'd use a for loop to copy two arrays. If you're copying a dynamic array to another dynamic array, you can simply set them equal to each other, like this: var array<int> TestArray; var array<int> CopyArray; function PostBeginPlay() { TestArray[0] = 9; TestArray[1] = 5; TestArray[2] = 6; CopyArray = TestArray; //This actually works!! } However, as soon as static arrays are involved, that won't work. What you'd probably want to do then would be something like: var int TestArray[3]; var array<int> CopyArray; function PostBeginPlay() { local int i; TestArray[0] = 9; TestArray[1] = 5; TestArray[2] = 6; //Copy the array for( i = 0; i < ArraySize(TestArray); i++ ) { TestArray[i] = CopyArray[i]; } }   Also, when I said that writing CopyArray[CopyArray.length] was the same thing as writing CopyArray[0], I meant that only for the first time that line was written (when CopyArray.length was equal to 0). And dynamic arrays are pre-initialized with a length of 0, but when they are extended, the array's length variable will change BEFORE the right-hand side of the line is executed. Sort of confusing, and you'll rarely encounter code where you need to know that, but it's always nice to know. :D
10. ## [Update 8pm GMT] UDK: Model's animations aren't playing!

Nope, you can put it anywhere you want (though the package itself should be somewhere in the Content folder). And don't worry about the file type and path... unless you're like me and you enjoy typing all of it out StaticMesh=TexPropCube_Dup would get you the same result as StaticMesh=StaticMesh'UN_SimpleMeshes.TexPropCube_Dup'.     If you only want the mesh attached to the player for one part of the level or for some other scripted event, it might be better to use the AttachToActor node in Kismet. If you want the mesh attached all the time though, it'd probably be better to have it in Unrealscript. Also, you can only attach to an actor in Kismet, but in Unrealscript, you can attach components to an actor or to the actor's SkeletalMeshComponents.   If you're attaching something to the player, then you'll be attaching directly to the actor (as opposed to if you were attaching something to an enemy pawn, where you'd be attaching to the actor's body mesh). One way is with the DefaultProperties like you have written out. Another way is to create and attach the components dynamically, which would look something like this: var() SkeletalMeshComp Comp; //Can also be a StaticMeshComponent.... or any other component type function AttachMesh() { Comp = new(self) class'SkeletalMeshComponent'; Comp.SetSkeletalMesh( WhateverMesh ); Comp.SetLightEnvironment( MyLightEnvironment ); AttachComponent( Comp ); } You can use a local variable instead for the component you're attaching, but if you later want to detach it from the actor, play an animation, etc, it'll be easier if you kept the variable. Now to animations... Unless you're using an AnimTree, you're going to have to call the animations using the SkeletalMeshComponent's PlayAnim(name AnimName, optional float Duration, optional bool bLoop) function (I left out the rest of the optional variables but those are the main ones you'll be using). It's not difficult, but you'll want to avoid playing an animation while an existing one is being played on the component, as the first animation will be stopped and can be pretty ugly unless the first animation is something subtle like a weapon's idle animation. Also, you're going to need to have an AnimNodeSequence to play the animations on (see code below).   Since static meshes can't play anims, I'm going to pretend that the TexPropCube_Dup is a skeletal mesh for an example. class BreakDancingCube extends Actor placeable; var() SkeletalMeshComponent CubeMesh; var name CubeMeshAnim; simulated function PostBeginPlay() { super.PostBeginPlay(); CubeMesh.PlayAnim( CubeMeshAnim,, True ); //Play a looping animation } DefaultProperties { Begin Object Class=AnimNodeSequence Name=MeshSequenceA //Don't need to change any settings, but you need to create it End Object Begin Object Class=SkeletalMeshComponent Name=BasicMesh SkeletalMesh=SkeletalMesh'UN_SimpleMeshes.TexPropCube_Dup' AnimSets(0)=AnimSet'UN_SimpleMeshes.TexPropCube_Anims' //Totally made-up anim set Animations=MeshSequenceA //Animations won't play without this line Materials(0)=Material'EditorMaterials.WidgetMaterial_X' LightEnvironment=MyLightEnvironment Scale3D=(X=0.25,Y=0.25,Z=0.5) End Object CubeMesh=BasicMesh //So that we can reference this in the code Components.Add(BasicMesh) CubeMeshAnim=BreakDance //Made up anim name for the made up anim set }
11. ## Dynamic Arrays in UnrealScript...

That's exactly what it's doing... perhaps not the best way to do it, but it works none-the-less. :P   As for why you need to subract by 1, you need to understand three things. First of all, while the starting index of arrays is 0, the length variable starts at 1 (so an array with one element will only be indexed with 0, but will have a length of 1). Secondly, unlike static arrays, with unrealscript's dynamic arrays, you can extend an array simply by trying to write to an element out of the array's current bounds (so if CopyArray has 3 elements and you write to CopyArray[3], you will extend the array rather than getting an out of bounds error). And lastly, the length variable updates in real-time, so with the bolded lines, every time "CopyArray.length" is called a second time, CopyArray.length has already incremented.   Ehh, it's probably easier to see rather than have it explained, so I'll just go step-by-step through one of those lines.   CopyArray[CopyArray.length] = TestArray[CopyArray.length - 1]; At the start of the line, assuming this is the first time we wrote this, CopyArray has no elements, meaning it has a length of 0. CopyArray[CopyArray.length] is the same thing as writing CopyArray[0], meaning we just extended the array by one. So with the right hand side, CopyArray.length is 1 and to get the correct element from TestArray, we need the -1. Without that, when we reach the 3rd line, the code'll be accessing TestArray[3], which is out of the array's bounds.   Hope this explanation was somewhat understandable/helpful.
12. ## UDK - Changing Material When Player Walks

Yeah, that's definitely not something that kismet will be able to do... I looked through the Unrealscript terrain code and I don't see any easy way you'd be able to modify layer blending from there either. However, I'm not sure that modifing the layer blending would be the best way to acheive that effect in the first place. To get the patches to appear with a relative accuracy to where the player's feet are landing, the terrain would have to be tesselated way too densely. A better option might be to spawn a decal or particle system (or both) where the player's feet land, which wouldn't be too hard to implement, though you'd have to muck around in Unrealscript code.   I'm not sure if you're interested in doing that, but if you are, then basically all you'd have to do would be to extend the UTPawn class, modify the GetMaterialBelowFeet() function to store the material under the player's feet, and modify the ActuallyPlayFootstepSound(int FootDown) function to compare that material with whatever your mud material is and to spawn the corresponding decal/particle system if it's the right material (and then you'd have to extend the UTGame class to reference your pawn class instead of UTPawn). Not the most elegant solution, but it wouldn't require any additional functions and would keep the additional code required to a minimum.
13. ## [SOLVED] Reference the controller of a pawn?

The Controller variable is a valid reference to your pawn's controller, but it's of the class Controller. When you have MyPawn.Controller.BeStunned(), you're calling the function from the Controller class, which is where the error's coming from. You'll need to cast the Controller variable to get it working. Something like this should do the trick: MyController( MyPawn.Controller ).BeStunned(); It's also a good idea to check if the cast actually worked, but if the pawn's controller will always be MyController, it's not necessary (though still recommended). If you're going to be calling MyController functions a lot, it might be better to use a local variable instead of casting a bunch of times, like: function Whatever() { local MyController PC; PC = MyController( MyPawn.Controller ); if( PC != None ) { //Do function calls } }
14. ## [UDK] Clarity on the default inventory system, and removing a weapon

Ahh, no, ThrowWeapon() would spawn a DroppedPickup in its place. You'll have to remove the weapon directly with the InventoryManager's RemoveFromInventory(Inventory ItemToRemove) function. I wrote out what to do, but then where's the fun in that? I'll let you have your fun figuring it out instead of just giving you the answers
15. ## [UDK] Clarity on the default inventory system, and removing a weapon

The DefaultInventory's given to the player when they're spawned. After that, the weapon will be in the InventoryManager, and you'll have to use the DropFrom(vector StartLocation, vector StartVelocity) function from the inventory class to get the pawn to throw out its current weapon... Luckily, that's already done for you with the PlayerController's ThrowWeapon() function (which calls the Pawn's ThrowActiveWeapon() function), so you don't need to make the function at all.