Playmaker Forum
PlayMaker Help & Tips => PlayMaker Help => Topic started by: coxy17 on September 27, 2013, 10:33:39 AM
-
Hi, Im new to unity and i am experimenting with Unity and Playmaker. I Want to make a character (just a cube atm) be able to walk around an object going against gravity.
The best example i can give is with the game Kula World, where the ball can move around some blocks. But when you jump off you fall as usual.
e.g. (go to 3:40 to see what i mean)
Is this possible in Playmaker or will I have to write a script?
-
Hi,
I would use raycasting for this. Simply raycast ahead of the cube, if it finds nothing, check if you have a new route or side to the ground, and then conform to it.
But it's not trivial to build for sure, so be prepare for some experimentation and trial/error quality time :)
bye,
Jean
-
Hi Jeanfabre
ok ill give it a shot. Thanks for the guideance. I was using Blender (python) and managed to achieve this but do not understand Unity fully yet. Heres my code from that game if anyone knows python to convert? *ignore key controllers.
Thanks again
from bge import logic, events
#from bge import render
from mathutils import Vector
from math import pi
tic_rate = logic.getLogicTicRate()
gravity = 20
turn_speed = 0.05
move_speed = 2.5
jump_force = 500.0
up_key = events.UPARROWKEY
down_key = events.DOWNARROWKEY
left_key = events.LEFTARROWKEY
right_key = events.RIGHTARROWKEY
run_key = events.LEFTCTRLKEY
jump_key = events.XKEY
class Translation:
def __init__(self, own, sensors):
self.own = own
self.floor = own
self.col_floor = sensors[1]
self.velocity = Vector()
self.rotation = Vector()
self.force = Vector()
self.gravity = Vector((0, 0, -gravity))
self.normal = Vector((0, 0, 1))
def keyboard(self, just_activated=1, active=2):
events = logic.keyboard.events
left = events[left_key] is active
right = events[right_key] is active
up = events[up_key] is active
down = events[down_key] is active
jump = events[jump_key] is just_activated
move = up - down
turn = left - right
return turn, move, jump
def get_normal(self):
ori = self.own.worldOrientation
start = self.own.worldPosition
end = self.floor.worldPosition
# render.drawLine(start, end, [1, 1, 0])
hit_normal = self.own.rayCast(end, start, 1)[2]
if hit_normal:
self.normal = hit_normal
def main(self):
turn, move, jump = self.keyboard()
self.rotation.z = turn * turn_speed
if self.col_floor.positive:
self.floor = self.col_floor.hitObject
self.velocity.x = move * move_speed
self.force.z = jump * jump_force
self.get_normal()
self.own.localLinearVelocity.xy = self.velocity.xy
self.own.applyForce(self.force + self.gravity, True)
self.own.alignAxisToVect(self.normal, 2, move_speed / 20)
self.own.applyRotation(self.rotation, True)
def box(cont):
own = cont.owner
sensors = cont.sensors
if 'translation' not in own:
own['translation'] = Translation(own, sensors)
own['translation'].main()
def mesh(cont):
own = cont.owner
velocity = own.parent.localLinearVelocity.x
own.applyRotation([0, velocity * pi / 2 / tic_rate, 0], True)
-
Hi, I have found this script on the Unity forum (http://answers.unity3d.com/questions/536740/magnetic-ball.html# (http://answers.unity3d.com/questions/536740/magnetic-ball.html#) and was wondering if it would work for what i am trying to achieve as i cant get the code to work :( . Could this be made just in Playmaker?
Thanks
Nick
-
You can script in Unity using Boo, which is a Python variant...
-
Hi Mike,
I could but i don't know about boo. Hardest part is understanding what BGE controls can be replaced with Unity? I feel like im not going to get anywhere with this. i guess there's not a clear answer. All of the guides online point to planets and not flat object e.g. Cube.
-
Hi,
I have added this to my list of samples to do ( that huge list yes...). But it's low priority I am afraid, I have to keep up with what's currently supported on the wiki and finish that round first. So don't hesitate to contact me if you need something quick or if part of a project with a budget, we can see how to properly implement such system.
Bye,
Jean
-
Hi, Ive got a script which could be made in Playmaker but dont know how to go about it? The code has not been error checked. Just a guide. Would be great if anyone could create a demo.
private Vector3 surfaceNormal;
private Vector3 personalNormal;
private float personalGravity = 9.8f;
private float normalSwitchRange = 5.0f;
public void Start()
{
personalNormal = transform.up; // Start with "normal" normal
rigidbody.freezeRotation = true; // turn off physics rotation
}
public void FixedUpdate()
{
// Apply force taking into account character normal as personal gravity:
rigidbody.AddForce(-personalGravity * rigidbody.mass * personalNormal);
}
public void Update()
{
// we don't update personal normals in the case of jumping
if(!jumping)
{
UpdatePersonalNormal();
}
}
public void UpdatePersonalNormal()
{
RaycastHit hit; //hit register
// list of valid normals to check (all 6 axis)
Ray[] rays =
{
Vector3.up, Vector3.down,
Vector3.left, Vector3.right,
Vector3.forward, Vector3.backward
};
//for each valid normal...
foreach(Ray rayDirection in rays)
{
//check if we are near a cube face...
if(Physics.Raycast(rayDirection , hit, normalSwitchRange)
{
personalNormal = hit.Normal; //set personal normal ...
return; // and return as we are done
}
}
}
I havent added a jump button as im not sure how it will work with not updating personal normals.
Also when the physics switches, i can then add in rotational changes.
Nick
-
Hi,
Ok, first, your pseudo code is a bit odd, so I am not sure what you are trying to achieve here, but you will need to fiddle around I guess.
-- surface normal is not used
-- I assume you want to always have the local z axis as the personal normal, so you need to update this every update.
-- Freezing rotation, can be done by simply unchecked the rotations axis in the physics constraint section of the physics component, so no need to define it in your code.
Please find attached a working sample doing all this. Let me know if you understand how it's done.
bye,
Jean
-
ok i realise the code is a bit weird. Just trying to get a starting point. Ill look at the sample and if i have any luck ill post it up. :) thanks!
-
I understand the code you have submitted. Ive made this https://www.dropbox.com/s/3rx55rf32jvjv8e/test.avi (https://www.dropbox.com/s/3rx55rf32jvjv8e/test.avi) from my previous Python example to show you all the actions i want to achieve. Your logic works but im struggling to add in last bit of the characters functionality. Ive tried various option with raycasting and having the character rotate when hanging over the edge. Just cant make it like my video.
I must be missing something. Shall i upload my test file?
All this for a uni project lol
Thanks
Nick
-
Hi,
Ok, I have added this to the trello task list management. If you want to be part of it and vote for what to do next, pm me with your email to become a member of the board and vote up for your favorite tasks.
Bye,
Jean
-
Hi,
Ok, I finally had time to work on this, and given your requirement I went for the following approach:
instead of defining the gravity using the normal of the ground, I use a collider. Everytime you have a new "gravity" field on your level, have this collider for the player to trigger and I use that collider transform to deduce the gravity to apply from then on.
The direct benefit is that you define accuratly what gravity to apply and where. In the case of your cube ( if the level was just a cube), using the normal of the cube is tricky to get because your character would be falling, but then how do you know what face of the cube to catch as the new gravity, for this would would need to raycast in all directions of the player, which in turn would make it difficult to scale, because imagine you have a wall, then it would detect the wall and apply the gravity and you would then be attracted by the wall. It is possible to implement layers and ignore objects etc, but I felt this has too much constraints.
So, have a play with this setup and let me know, If you still need a ground based normal gravity, let me know, that's nothing difficult to implement, but then the player will only check for what's beneath himself, not what's surrounding, as implement htis would require a very specific description of how the game play should behave.
Bye,
Jean
-
Thanks Jean,
I will take a look and let you know :)
Nick
-
Hi Jean,
How can you rotate a player when entering a trigger and set the Y direction to the trigger just entered? i can sort of see how to apply it but this is the only part im struggling to understand. The rest is great!!!!!! i can apply what you have supplied to what im trying to achieve.
Just need to know how to 'get' and 'set' the player orientation on entering a trigger to the triggers world position.
Thanks so much!
Nick
-
Hi,
Very good.
Ok, you don't set the gravity based on the trigger world position, instead you set the gravity based on the trigger orientation. Does that make sense?
Open the "level" gamObject and select one of its "Gravity Trigger" gamobject.
-- in there you have a fsm with a simple "TRIGGER ENTER" listener that broadcast in turn a "GRAVITY TRIGGER" global event.
-- the "Gravity Manager" catch this "GRAVITY TRIGGER" global event in the fsm "Gravity Manager", it gets the actual collider, and compute it's -Y direction which is the direction of the gravity for that trigger ( basically your world gravity becomes relative to this collider transform orientation, Y means up, -Y means down).
-- Then the "Gravity Manager" fire an event to the ball itself to "SET GRAVITY".
Does that clarify things?
bye,
Jean
-
Ok I understand that part now. Let say i wanted to rotate the player. Im just about to enter the trigger and the trigger is e.g. 90 degrees on its Y axis from the players Y axis. If i enter, can i rotate the player to match the Y axis of the Gravity Trigger?
I can do this manually by specifying the rotation but wondered if this could be dynamically?
This is my last question lol. I will put this to resolved if i can. :)
Thanks for your time!
Nick
-
Hi,
yes, you simply have the player look forward using the "up" vector as the Y axis of the collider he just hit.
bye,
Jean
-
Thanks Jean!!!!! i got it to work! woop! :D
-
Hey, Sorry after i implemented i realised that the player doesn't always align up? im using the same principle as the Camera Adjustment (look at ball). But just using the player to adjust self. But it tends to over rotate to far forward?
Im thinking ive done the setup wrong. Nearly achieves what i want to do.
Ive included a link from my dropbox showing screenshot of the setup i have as trying to upload one here throws back a database error? Any further guidance would be greatly appreciated!
https://www.dropbox.com/s/lln4rb3te8nxswz/player%20adjustment.jpg (https://www.dropbox.com/s/lln4rb3te8nxswz/player%20adjustment.jpg)
Sorry to be a pain!
-
Hi,
Does it align up for a while and then stop? it could be because you simply stop looking?
-
Hi, Yes you are right. simple mistake. Finally there!!!! thanks for all your help!!!!!
-
Hi Jean,
I noticed an issue with the 'smooth look at direction 2' action. When i get the 'velocity' of the 'direction' and i apply this every frame it sometimes auto rotates the player back to the original position and not the triggers (or another random direction). Ive posted here as it relates to this post and didnt want to make another.
1. Player enters trigger
2. Player auto rotates and positions fine (always checking)
3. Sometimes the player keeps on flickering and don't find the new direction and stops in the weird position (there is no way of always replicating this, it seems like its random/buggy) it seems to occur when catching the edge of the trigger?
Ive captured the video to show you what happens. I have highlighted the trigger to show where it is before i clicked play. The first time i go back to the trigger (0:18) is when the random auto rotation occurs. the 2nd time i enter (0:26) it enters fine and remains int he same direction?
https://www.dropbox.com/s/3hysnxo97oq6het/test%20trigger.avi (https://www.dropbox.com/s/3hysnxo97oq6het/test%20trigger.avi)
Thanks
Nick
-
Hi,
gravity triggers and the ball look at are not linked at all, the ball is only checking for its own velocity, It's not a problem with the action per say, it's a problem of design.
In your case, you might want to no use the ball velocity for the camera work but just the last trigger, just like it defines the gravity it would define the forward direction for the camera work.
Does that make sense?
bye,
Jean
-
Hi,
i sort of understand, I have setup the 'trigger' to get its velocity and sore in a global variable. Then i used 'smooth look at direction 2' on the player and it always looks at its Z axis.
But the problem is when i enter the trigger going against the triggers Z axis and it always flips the player 180 degrees around when the player stops inside. What am i doing wrong? I think i might of not understood lol.
-
Hi,
You are simply facing a problem of design. All of the tools you are using are working, it's just that it doesn't end up being something logical from a user point of view.
in our case, I would still use the actual player velocity to compute the camera work, but actually implement a threshold so that if the player speed is léower then a certain value the camery only follow the position, not the orientation.
You'll likely have to resort to that kind of tricks to get all of this right.
bye,
Jean
-
Hi Jean,
I understand what you are referring to now. Frustrating lol. Could I use the triggers velocity and combine it with the players velocity? i mean to float the X,Y or Z and do something there? just speculating, might be talking rubbish as im still fairly new to Unity Scripting.
Ive looked into Vector3.RoateTowards, is this something that I could possibly experiment with?
The camera work is fine now, however, the player when entering a new trigger rotates but not to the triggers velocity? it seems to be keeping its own world XYZ?
thanks
Nick
-
Hi,
I think you are facing some angle issues more than anything else. The best way is to experiment for sure.
Combining velocity is not a good idea I think, what you want is a simpler approach. But using the trigger axis to define the camera angle would be the way to go, it would not rotate with the player, only follow the player position while keeping the current trigger camera orientation. So you only orient the camera once when hitting a new trigger and simply kep matching the player position ( and not its orientation)
Bye,
Jean
-
Hi,
Yes I get what your are on about, it is an angle issue. The problem is more with the player being at the wrong angle when entering first trigger. It doesnt align straight so when i use my keys to move the player forward, it wont as its XYZ isnt the same as the trigger, causing it to move incorrectly (wrond direction to the trigger XYZ).
Could i use Quaternions to achieve the rotation? possibly Lerp?
Nick
-
Hi,
The problem would stay the same, as it is by design, you need to find a new way for your camera or character behavior. the one way out of this as I think of it is to only have the camera rotating when the character speed is greater than a threshold valud, so that if the character turn in place, the camera won't move. OR you could only turn if the player is moving forward, that would work too.
Bye,
Jean
-
Hi Jean,
Ive finally got somewhere with it and im just trying to get the character to move. Ive attached a screenshot of the movement FSM you included in the game. I am happy about how the character moves forward but i need the character to rotate based on a variable. Lets say 40 degrees.
I have a KeyDown for each movement already but i cant seem to use the rotate event to set a particular angle. I think i need to do something with the attached FSM setup. Ive read through each event of yours but not sure what to change? i have also tried a separate FSM on top to see if i could use rotate but for some reason doesnt rotate the player at all. The player hasn't got a freezed position.
Any advice would be most greatful!
Nick
-
Hi,
Completly seperate the rotation and the movement, make it two distinct fsm and this will be easier to deal with, here your state stack is a bit long... and you won't have the flexibility that you could have with two fsm.
bye,
Jean
-
Hi Jean,
I understand what you mean, so i cant just simply use the rotate event as its a Vector3. Could you give me an example of a left turn please? ive separated it out but i must be missing something. Cant upload it as this site has an error.
Kind regards
Nick
-
Hi,
Ok, please find a working sample of a physics based move and rotate controller. They work as separate Fsm. So you should experiment with this base to achieve your behavior.
If that's not suitable or missing the point, let me know.
Bye,
Jean
-
Hi Jean,
Thanks for the demo.
I get the Axis and store it. (I specify the Multiplier to 1.)
I use Float Multiply to get the desired X number.
I rotate based upon the SideWay Input.
I can see it rotates but doesnt take the camera with it. I havent put this in place yet. Not sure how? ive still left in the original Transform direction from your previous demo.
thanks for you help so far!
Nick
-
Hi,
Can you make your camera question as a new threa? that will be easier for future researchs.
bye,
Jean
-
Ok, will do.
-
Hi Jean,
I have started a new topic (http://hutonggames.com/playmakerforum/index.php?topic=5804.0 (http://hutonggames.com/playmakerforum/index.php?topic=5804.0)) but ive tried explaining what im trying to achieve but I am unable to explain further to 'Lane'. Would you be able to help me? as it relates to what you was helping me with.
after i want to put a demo up for people to use apart of the topics if that's possible on this forum? this is just the last piece of my puzzle lol.
thanks :)
Nick
-
hi,
i would do a look at or a smooth look at, have your player looking at the trigger, if you set the up vector to be the y axis of the trigger, it will work ok.
bye,
jean
-
Hi jean,
Ive tried manually setting one of the triggers and the TargetObject and its works :)
but not sure how to get the different triggers axis as a TargetObject as i enter it? instead of just specifying one.
Thanks again
Nick
-
Hi
Figured it out now, just used a variable
Thanks,
Nick