I'm trying to build an Input Handler in Coco2D-x for a 3D game.
I want to control the camera rotation using the mouse, like an FPS. To achieve this, I need to store the previous and current mouse position every frame to calculate the delta movement per frame and apply it as a rotation.
The only way that the documentation shows to get the mouse info, is through Mouse Events and the Event Dispatcher. I tried that, but it is not useful for the position because, that way, I will only refresh the previous and current position when the mouse moves. if the mouse doesn't move, I still have some delta movement (calculated N frames ago, when the mouse moved the last time) and the camera will move forever.
Is there any way to get the position of the mouse every frame?
I'm also open to any suggestions on how do the camera movement with the mouse.
I'm using Cocos2d-x 3.13.1 and Visual Studio 2015 on Windows 10. The project is on C++.
Thanks.
I am not an expert on Cocos2D, but from this:
The only way that the documentation shows to get the mouse info, is
through Mouse Events and the Event Dispatcher. I tried that, but it is
not useful for the position because, that way, I will only refresh the
previous and current position when the mouse moves. if the mouse
doesn't move, I still have some delta movement (calculated N frames
ago, when the mouse moved the last time) and the camera will move
forever.
I think that resetting the deltas to 0 after the camera rotation calculations will solve your problem using these events.
I found a solution, maybe not the best, but the easiest one.
InputHandler is still in control of the mouse events, and it only stores the current position of the mouse. This position is updated only when the mouse is moved.
CameraController is asking, every frame, for the current position of the mouse. Before doing this, it's storing the previous one.
That way, I can control if the mouse moves or not.
So basically I calculate the delta wherever is necessary (camera controller in this case) instead of calculate it every frame (as I intended with the Input Controller).
This is within the update function in CameraController
mousePreviousPos = mouseCurrentPos;
mouseCurrentPos = inputHandler->GetMousePos();
mouseDelta = mousePreviousPos - mouseCurrentPos;
if (mouseDelta.x != 0)
{
ApplyRotationAroundY(mouseDelta.x);
}
if (mouseDelta.y != 0)
{
ApplyRotationAroundX(mouseDelta.y);
}
I will stay tunned for more or better solutions.
Thanks!
Related
I am trying to do some cad operations like zoom, rotate and pan. I want to provide a button for each operation and do the corresponding operation on click.
The controls should automatically allow the user to use the mouse to perform those operations. Button controls wouldn't be as smooth or freeform as the default controls, since a click has no direction or duration. For instance, a rotate button would only be able to rotate a certain number of radians at a time in one direction, while the default controls allow for any amount of rotation.
But if you do really want buttons, I'd suggest implementing them in the following ways:
Zoom: Two buttons to move the camera's position a certain amount forward or backward.
Rotate: Buttons rotate the object n radians.
Pan: Buttons shift the camera's position left or right.
You may notice that none of these solutions use Trackballcontrols. Trackballcontrols is a set of mouse controls, it's not meant to be transferred to button commands. You can achieve the same result much more simply by assigning functions to the buttons that change the object's or camera's rotation or position. I think you'll find the following list useful: https://threejs.org/docs/#api/en/core/Object3D. Look at the rotate and translate methods.
I am trying to do a navigation system like google cloud infrastructure like this:
google cloud infrastructure.
I want to do this using aframe rather than threejs. So I am now customising aframe orbit control by keven ngo:
aframe orbit control.
The problem is that, I succeeded in limiting the auto rotation in a certain angle, so as pan. But I have some following problem that I do not know how to do after searching every posiblities and tried my self:
how to achieve the same effect of bouncing back smoothly after reaching out the pan limit;
for some reason if I pan and after mouseup then when mouse moves, it still pans rather than rotate. Why is that?
how to make camera rotates slightly like in google's example(I modified the original library to rotate camera when mousemove rahter than mousedown)?
Below is the glitch link of my experiment:
aframe customized orbit control
what I customized(I notated my change with slashes and ADDITION text):
autorotates between set angle;
mouse click only pans; when mouse move, camera rotates and autorotate stops;
pan can be limited.
This is a long question, very appreciated if anyone can help!!
how to achieve the same effect of bouncing back smoothly after reaching out the pan limit?
One idea: on mouseup (ie release of pan mode), check if the camera target is outside of the camera's viewing frustrum. If so, calculate a new target position, say half way between current target position, and a point in line with the camera z axis( ie, the center of the screen). Then make an animation, that moves the camera target from current location, to new location.
for some reason if I pan and after mouseup then when mouse moves, it still pans rather than rotate. Why is that?
It seems that the navigation mode (panning, orbitting,or zooming), does not change on mouse up. Make a new (mouseup) listener, that forces orbit mode back to a default mode (orbit?).
how to make camera rotates slightly like in google's example(I modified the original library to rotate camera when mousemove rahter than mousedown)?
It looks like in the google example, orbit direction is determined by which side of center the cursor is in. Left side makes autorotate go clockwise, and right side counterclockwise. You will need to use the cursor component to detect this, and change the orbit direction accordingly.
Also, it appears that in the google version, orbitting is not determined by mousedown (ie dragging), but by cursor distance to center, and this is added to the auto rotate. It appears to be a buffer system, where distance to center initially creates a value to alter the auto orbit (by adding or subtracting to the orbit amount), but that value is a buffer, meaning that it degrades to 0 over time (each frame the value is reduced slowly to 0).
I am using ThreeJS's OrbitControls so that when an object in my scene is clicked, the camera travels close to it and and starts orbiting around it. I'm just moving the controls.target position, camera position and setting controls.autoRotate = true.
The clicked object gets centered on screen, which is nice, but sometimes I need to show a text covering up to 50% of the bottom area of the screen, and then the selected objects gets hidden by it. So, I'd need to somehow offset the rotation center up a bit.
Perhaps another way of asking this is that I need to change the center of rotation so that it is NOT the center of the screen (or the center of the renderer canvas)
I've tried moving the target up but, of course, then the camera doesn't orbit around the selected 3D object but around an empty space close to it. Any idea on how to proceed?
Many thanks!
I finally got the desired results following the comments in this other thread:
by using camera.setViewOffset
I just recently began using Unity3D and this is my first game, so if I'm not doing things like I'm supposed to, please tell me.
There is a 2D character that I want to move one step forward using the Animation mechanism. This movement can be splitted in two parts :
Move forward the back leg, don't move the upper body ;
Use this leg to push and make the step, moving the upper body.
My problème is that I can't find a way to make this step permanent. As soon as it start looping on the "Idle" animation, then, it come back to the original position (before the step).
I don't know how to let my character stay in the position it was just between the "Step Forward" animation and the "Idle" animation.
I tried to add "Rigidbody 2D", "Box Collider 2D" and "Physics2D Material" on both feet and on the floor, but it somewhat breaks the IK script ("Simple CCD", from the youtube video "Unite 2014 - 2D Best Practices In Unity"). And I'm sure there is a much simpler way.
EDIT: My question was not clear enough. The idle animation is the default animation, where the character is doing nothing in particular. It's just moving a little while it's staying in position. When it runs "Step Forward", all the sprites are moved (only when the back leg is pushing). If all animations are stopped right now, then the character is indeed in a new position, closer to it's opponent. I can check that by removing the transition from "Step Forward" to "Idle". But from here, I want it to loop on the Idle animation. When the transition from "Step forward" to "Idle" is done, the character is NOT running Idle from it's new position, but from it's old position, before the step, as if it was pulled from backward. I want to run Idle from the new position.
Here is a longer gif when we can see more of the Idle animation :
And my Hierarchy panel looks like :
Main Camera
Karateka (the top GameObject container, with the Animator component)
Torso (the sprites)
Head
Right arm
Right leg
Right lower leg
Right foot
...
IK (the Inverse Kinematics targets)
Left fist target
Left foot target
...
Any suggestion is welcome.
If I get it right, you have the StepForward animation running and it gets cut in the middle back to idle. There, the StepForward animation triggers again but from the start and you wish to restart from where you left off:
You can record the normalized value of your StepForward animation and use it next time:
float normValue = this.animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
then you can use that value:
this.animator.Play("StepForward", 0, normValue);
Other possibility, you are not after that but simply you want to pause the animation without getting to Idle.
Use a parameter. You can add a float parameter (call it direction) in the Animator window (top left). Then select a state in the animator, it will open the animation setting in the inspector. Under speed, open the drop down where your new parameter should show up. And tick it.
Now, your direction float will affect the speed of your animation as such:
this.animator.SetFloat("direction", value);
if you give 0, you pause. Give back 1 to move forward. You can also lerp the value so it is not abrupt. Your way.
I'm making a 2D platformer and I've come across a really annoying problem where if I move my player character GameObject to another location on the scene, my player becomes stuck and the game spazzes out, jumping from the players original location and the position I moved it to.
My player character is made up of many parts, each a separate GameObject. I know the problem is definitely in my animation, because if I disable the animator component, the problem goes away, just I don't have my animations anymore. I believe the problem may be in the player character's Idle Animation and it's position property. There is no script attached where his starting location is hard coded.
How can I make the child Gameobjects move relative to the parent Player GameObject? I cannot move the player in the scene from its original location without the game glitching up.
Here are some screenshots
[Player and it's parts in Hierarchy]http://i67.tinypic.com/bdlc1j.png
[Idle Animation]http://i64.tinypic.com/2gtp99x.png
[Player's original Location, he works if starting here] http://i66.tinypic.com/261jb6c.png
[Player is Moved, game bugs out] http://i67.tinypic.com/292a2c3.png
Try to disable "Apply Root Motion" flag in the Animator component.
The problem should be related to the fact that the animation changes the position values
My guess is that you have animated the different parts by moving then around in the editor and recording that. This meas that the animation is keeping track of the original position at which you did the animation. Try deleting those parts from the animation.
I couldn't fix the spazzy-jittering problem that occurs when I move the player character to another position on the scene, but I did find a way around it. The problem definitely lied within the Animator component and the gameObject's Rigidbody2d.
Instead of moving the player to another position, I instead made a 'Spawn Point' which the player starts from when first playing the scene, and that was able to be moved freely around. Pretty much:
void start(){
transform.position = spawnPoint.transform.position;
}