How do I set camera to chase an entity, but only in x direction? - andengine

So I have a small Sprite, and I want it to be able to jump/fly but I don't want the camera to follow its y movements, just the x movement. Is this possible?

You need to use BoundCamera class or its extensions to be able to access methods responsible for setting camera bounds.
Entity e = new Entity();
e.setPosition(pX, pY);
camera.setChaseEntity(e);
camera.setBounds(0, 0, 800, 50);
camera.setBoundsEnabled(true);
First two parameter are minimal X and Y bound position (in this case bottom left corner) Two next are maximum bound position. Which means camera`s position will not exceed 800 x and 50 y value.Change as per your requirement.Hoping it may helps you.

Related

Weird output debugging the forward of an object with InverseTranformDirection

sorry for my bad english! I will try to explain the situation. Im just playing with this function because i want to understand how it works. The concept is really clear but debugging the forward of the object that i am debugging i get really weird output. For example im using InverTranformDirection(Vector3.Forward) to see what vector i get from the object child of another object. They are both perfectly aligned with their own axies. If i try rotate the parent of the object in order to have the forward pointing at (0,0,1) the child object that i am debugging has the same z axis value like it should have because they are alligned but if i rotate the parent to get the forward rotated on the (1,0,0) space cordinates, i get the cordinates inverted (-1,0,0). I mean why? Parent and child are pointing they own forward in the same exactly direction. Could you help me understand? Thanks!
InverseTranformDirection(Vector3.Forward)
wouldn't care about the parent at all. It is simply converting the world space global Z axis direction (= (0, 0, 1)) into local space of the according object.
I'd say it does exactly what you would expect.
Rotating your object to its own forward vector points towards (1,0,0) (=Vector3.right = world X axis) basically means the world space forward vector (0, 0, 1) (=Vector3.forward) is now pointing left away from your object.
Which is what (-1, 0, 0) would mean in its local space.
Vector3.forward (= -transform.right)
(world Z axis) (local negative X axis)
^
|
|
rotated Object ----> Vector3.right (= transform.forward)
(world X axis) (local Z axis)

Get x and y 'coordinates' from object speed and direction

I have a player object that controls like the ship in Asteroids, using speed and direction. This object is fixed in the middle of the screen, but can rotate. Movement of this object is a visual illusion as other objects move past it.
I need to get x and y coordinates of this player object, from an origin of (0, 0) at room start. x and y do not provide this info as the object does not move. Does anyone know how I can get 'fake coordinates', based on the speed and direction?
One thing to make sure is that you're not just getting x and y on their own, as that will get the current object's x and y position. Instead, make sure to reference the object you're trying to get. For example:
var objectX = myShip.x;
var objectY = myShip.y;
show_debug_message("x: " + string(objectX));
show_debug_message("y: " + string(objectY));
I think you are thinking about it wrong. You do not need "fake coordinates". Real coordinates are fine. Give the ship and asteroids/enemies whatever coordinates and velocity vectors you want; randomly generate them if the game is like Asteroids.
The coordinates do not have to be fake; it is just that when you render in your game loop, you render a particular frame of reference. If the origin is the center of the screen, when you paint an object at (x,y) paint it as though it were at (x - ship_x, y - ship_y) -- including the ship, which will be at (0,0). If you wanted to make rotation relative to the ship too, you could do the same thing with rotation.
Now, you have your question tagged as game-maker. I have no idea if game-maker lets you control how sprites are painted like this. If not then you need to maintain the real coordinates as separate properties of objects and let the official (x,y) coordinates be relative to the ship. The trouble with this is that you will have to update all of the objects everytime the ship moves. But like I said I don't know how GameMaker works -- if it is a problem maybe ask a question more specific to GameMaker.
You'll need to think what you'll use to move the ship around, but then use that code on different variables.
Normally, you'll update the x or y if you want to move the ship, but since you're not going to do that, simply use a custom variable that replaces the x and y value (like posx or posy), and use them on the code that would otherwise be used to move the ship around.

Constrained knockback

I have a playing field which is divided in 4 zones (as seen on the image below)
The player (blue) is on the second zone while there are 2 enemies (red) on the third zone. When the player throws an object and hits the enemy, the enemy is knockbacked in the next zone (4) but should stay within that zone.
If the enemy was being hit on the edge of the zone, I want him to still be in the zone 4 and not outside of it (if he got knocked back). I'm not sure if the direction of the hit matters in the calculation. The horizontal position (x) between the zone can be random, but should be constrained by the edges of the zone.
Question: When the enemy is hit, I want to calculate the knockback position while being constrained to the zone he will be knockbacked to.
Note that it can be on any shape of playing field (triangular, hexagonal, circular, ...)
New components
You can use the NavMesh systems to compute the next position of the enemy.
You can find those classes (Components) on github. They are official component, but still in development if I remember well, that's why they are on github.
Now, you can find many tutos over the internet showing you how to use those classes. Here is one good example, thanks to Brackeys.
How it will work
Once you have downloaded thoses classes, you will be able to do as the following
I created a very basic scene in which a wolf needs to go to the cross position (on right part of the image) but is not allowed to go on the lightest blue on the map (right part of the image, you can see a line in the middle). So the navs components will compute the closest point, as shown as the middle of a circle (left part). You can manually add an offset not to be exactly on the edge if you want.
You can find more informations here.
This method computes the closest point of a given position.
Compute the knockback position
Regarding your comments, to compute the knockback position, there is differents ways :
Axis-based position
If your scene is as simple as those rules :
Left to right is X axis
Top to bottom is Y axis
(or the opposite)
Then you can do as the following :
public Vector3 GetKnockbackPosition(Vector3 startPosition, float force)
{
Vector3 res = startPosition;
res.x -= force; // Could be Z axis, depends on orientation
return res;
}
Not axis-based position
You can do as the following :
public Vector3 GetKnockbackPosition(Transform transformToKnockback, float force)
{
Vector3 res = transformToKnockback.position;
res -= transformToKnockback.forward * force;
return res;
}
Here you have the forward which will help you. You can substract this value and add a force factor to control the knockback force.
So once you have computed the position, you can use SamplePosition to adjust it, whether or not it is inside a zone.
Tell me if something is not properly explained.

Unity3D - Relative position on y-axis independent of rotation?

I have an object (A) with another object (B) next to it. I am trying to calculate the "height" of object B, so that i can position another object at that height relative to the position of object A. I know this sounds like gibberish (i'm a bit tired) so i have put diagrams to try and explain.
So in the left image the yellow line represents what i am trying to calculate. I have an position (orange) on the surface of a cylinder (grey) (calculated position using mesh data) which i am trying to use to calculate the radius of the object (black line). To do this i need a position at the center of the object (grey) at the same height (red dot) so i can calculate the direction from one to the other and use the length (.magnitude) as the radius.
My problem is i can't work out, how i can calculate the height (yellow line) without rotation having any effect.
I currently use projectOnPlane however if i rotate the object as seen in the second image, the radius decreases significantly when it should be consistent as the object is not changing size.
Vector3 RadDirection = (Vector3.ProjectOnPlane(orangePoint, grey.transform.up) - Vector3.ProjectOnPlane(grey.transform.position, grey.transform.up));
float radius = RadDirection.magnitude;
Any help would be much appreciated, thanks.
**UPDATE: The grey block in the diagram is a vector3 position rather than a game object. The radius calculation i am trying to do happens during runtime so i can't parent an object to the grey and review the inspector.
**UPDATE 2: Sorry, something i should have mentioned. The object i'm doing this on will not always be a perfect cylinder, it could be something such as a wine glass, where i need to calculate the radius of the glass not the stem. Another example could be a chemistry beaker which normally tapers to a point, so i would need to calculate the radius at the height of the orange point. Sorry i should have put that in the question.
Here's a diagram to illustrate what i mean in update 2. Again the orange dot is acting as a visual representation of a Vector3 position on the surface of the object's (in this case a beaker) mesh.
**Update 3: I appear to have solved the issue and so i have posted my answer below but at the time of writing i can't accept it (have to wait 2 days) and so cant close/answer the question. I would like to thank everyone that contributed and tried to help me solve this problem. I hope i can help you all someday :)
You can use transform.TransformDirection() or transform.InverseTransformDirection()
To get the height take the result of the subtraction and set the X, Z coordinate to zero:
Vector3 height = orangeBox.position - greenPoint.position;
height.x = 0;
height.z = 0;
Complete solution:
Vector3 direction = orangeBox.position - greenPoint.position;
direction = greyBox.transform.InverseTransformDirection(direction);
direction.x = 0;
direction.z = 0;
height = direction.magnitude;
redPoint.position = greenPoint.position + greyBox.transform.up * height;
I appear to have solved my problem using the following:
public static Vector3 ProjectPointOnLine(Vector3 linePoint, Vector3 lineVec, Vector3 point)
{
//get vector from point on line to point in space
Vector3 linePointToPoint = point - linePoint;
float t = Vector3.Dot(linePointToPoint, lineVec);
return linePoint + lineVec * t;
}
I found this here, it has lot's of other useful looking functions:
http://wiki.unity3d.com/index.php/3d_Math_functions
I basically pass in the origin of the beaker (green point) as the "linePoint", the upwards direction of the beaker "lineVec" with beaker.transform.up and finally i pass in the world vector3 point on the surface of the beaker mesh (orange point) it returns back a point in the middle of the beaker at the same height as my orange dot. I then just subtract the one from the other and take the magnitude as the radius. The radius value calculated is correct in that's it the value i was expecting and only changes after the sixth decimal place during rotation which gives plenty of accuracy as i only need three or four decimal places.
I'm happy to provide further details or help if anyone else needs help doing this.

How to increase (animate) the width of the square on both ends?

I have created a square that is 40x40, as shown above. I have a 4x40 strip that I'd like to use to animate (increase) the width of my square till it takes the the width of the whole screen within a second, regardless of the square's position. Quite similar to that of a progress bar loading on both sides.
UPDATE
I forgot to mention that the square is a physics body, hence the physics body must also increase as the sprite increases.
What you want to do is use SKAction.scaleXTo to achieve what you are looking for:
SKAction.scaleXTo(sceneWidth / spriteWidth, duration: 1).
Now if you want the left and right side to not scale evenly, but instead reach both edges at the same time, what you can do is change the anchor point.
The math behind this assumes that your original anchor point is (0.5,0.5)
sprite.anchorPoint = CGPointMake(sprite.position.x / scene.width,sprite.anchorPoint.y)
E.G. Scene size width is 100, sprite is at x 75
What this is basically saying is that your sprite is at some percentage of the scene, in case of the example, 75%. so by changing the anchor point to .75, what is going to happen is the left side will fill faster than the right side when you are expanding your width since the left side of the anchor point has 75% of the width, and the right side has 25% of the width .
Lets say we set the scale to 2, that means the left side of the anchor point will now be at 150%, while the right side will be at 50%.
In general, assuming the origin of your objects are in the top-left (or at least the left, since we're only changing things on one axis) if you set start_x to the original x position of your square, start_width to its width, target_x to the x position of your strip, and target_width to its width, then:
x = start_x + (target_x - start_x) * a;
and
width = start_width + (target_width - start_width) * a;
And as a goes from 0.0 to 1.0, x and width will grow to match the strip.
Hope this helps.