I have been making a top down 2d game and have come across a small issue. I need the player to stay within the screen bounds at all times. I have seen people with this problem before and have tried their solutions however none of them have worked with my game. This is because my player character uses physics to move around. This is what I have inside my FixedUpdate function:
minScreenBounds = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 0));
maxScreenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0));
transform.position = new Vector3(Mathf.Clamp(transform.position.x, minScreenBounds.x + 1, maxScreenBounds.x - 1), Mathf.Clamp(transform.position.y, minScreenBounds.y + 1, maxScreenBounds.y - 1), transform.position.z);
If anyone knows how to fix this I would much appreciate it if you could tell me how.
Many Thanks,
Tommy
Make 4 kinematic Rigidbody2D to the screen edges, like below (green colliders), and manage their scale / position for your need.
Related
I am creating a mobile top down shooter with Unity and my problem is that aiming with the joystick feels very stagnant.
It's like the joystick knows about 100 different directions, but I need 1000. I hope this is somewhat understandable what I mean. The joystick just doesn't feel smooth.
Is there any way to change this? Something like increasing a sampling rate so that the screen on the smartphone detects even the smallest changes?
For the joystick I use the following asset:
https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631
The implementation of my rotation and trying to make it smooth looks like this:
float eulerY = (Mathf.Atan2(_JoystickShoot.Direction.x, _JoystickShoot.Direction.y) * 180 / Mathf.PI);
if(_LastJoystickShootEulerY == 0.0f || Mathf.DeltaAngle(eulerY, _LastJoystickShootEulerY) > 30)
_Weapon.GetBarrelContainer().transform.rotation = Quaternion.Euler(0, eulerY, 0);
else
_Weapon.GetBarrelContainer().transform.rotation = Quaternion.Lerp(Quaternion.Euler(0, _LastJoystickShootEulerY, 0), Quaternion.Euler(0, eulerY, 0), 0.5f);
_LastJoystickShootEulerY = eulerY;
I am trying to create a 3d game like ketchapp ball race, in which the cube slides along a road, and the left right movement is controlled using touch
The problem I am facing is that the touch senstivity seems to react different on different devices, due to which I am not able to calculate the left-right displacement for all devices.
This is how I am calculating the left-right displacement of the cube:
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition ;
transform.Translate(touchDeltaPosition.x * .1f * Time.deltaTime, 0, 0);
However this is not working properly all device . Any help will be highly appreciated
See this answer: https://stackoverflow.com/a/25740565/10063126
Basically, ScreenToWorldPoint was used.
World position is computed; not screen touch position.
But you have to manually solve for delta position.
Example:
Vector3 currPos = Input.mousePosition;
Vector3 startPos = Camera.main.ScreenToWorldPoint(currPos);
Vector3 endPos = Camera.main.ScreenToWorldPoint(prevPos);
Vector3 deltaPos = endPos - startPos;
transform.Translate(deltaPos.x * sensitivity * Time.deltaTime, 0, 0);
prevPos = currPos;
How about using 2 buttons on your screen one for left control and one for right control and then when the left button is pressed you can give a value to go left and same for right button. This way your ball's movement will be independent from the touched position's X value.
I'm trying to make whack a mole game using project tango.
When user start the game, the program will create holes at random point for the moles to come out. Right now, I already can make the hole and spawn the mole at random, though I have a problem with the created hole.
The hole sometimes spawn at an edge contour of table and stuff and make the hole partially floating in the air. Is there any way to check if the centerPlane is near an edge or not?
Here's the screenshot of the problem I meant. I want the "hole" not to spawn on area that doesn't fit with it's height and width. Currently, I'm using farandole release.
EDIT 1:
I'm trying to do as Hristo suggest. But it doesn't work, the FindClosestPoint always return -1, even when I use the center of the screen. Here's the script I used. And for some additional info, I'm using the unitySDK and unity 5.5.2f1
bool CheckTheCorner(Camera cam,Vector3 planeCenter){
Vector2 firstPointInScreen = WorldToScreenConverter(cam,new Vector3 (planeCenter.x,planeCenter.y,planeCenter.z-holeheight));
Vector2 secondPointInScreen = WorldToScreenConverter(cam,new Vector3 (planeCenter.x,planeCenter.y,planeCenter.z+holeheight));
Vector2 thirdPointInScreen = WorldToScreenConverter(cam,new Vector3 (planeCenter.x-holewidth,planeCenter.y,planeCenter.z));
Vector2 fourthPointInScreen = WorldToScreenConverter(cam,new Vector3 (planeCenter.x+holewidth,planeCenter.y,planeCenter.z));
DebugText.text = m_pointCloud.FindClosestPoint (cam, new Vector2(Screen.width / 2, Screen.height / 2), 1).ToString ();
Vector3 firstPoint = m_pointCloud.m_points[m_pointCloud.FindClosestPoint(cam, firstPointInScreen, 1)];
Vector3 secondPoint = m_pointCloud.m_points[m_pointCloud.FindClosestPoint(cam, secondPointInScreen, 1)];
Vector3 thirdPoint = m_pointCloud.m_points[m_pointCloud.FindClosestPoint(cam, thirdPointInScreen, 1)];
Vector3 fourthPoint = m_pointCloud.m_points[m_pointCloud.FindClosestPoint(cam, fourthPointInScreen, 1)];
return false;
}
Vector2 WorldToScreenConverter(Camera cam,Vector3 worldPos){
Vector3 screenPos = cam.WorldToScreenPoint (worldPos);
return new Vector2 (screenPos.x,screenPos.z);
}
Ah yes, don't mind the return false one for the moment, I just put it there to avoid error since I'm still figuring out the FindClosestPoint.
What you can do is take the 4 corners on your plane and decide if they are all laying on a surface in the real world, if not you can make the plane elsewhere.
That can happen with the use of FindClosestPoint() method in the TangoPointCloud.cs. What that method does is makes a Raycast from your camera trough a certain point on the screen landing in the real world environment. The method then returns the index of that point. The list to search with the indexes is called m_points
So lets split it in steps:
Make 4 Vectors using the `FindClosestPoint().
Check if all 4 vectors are on the same plane (simple math).
If step 2 is true -> Instantiate your GameObject on that plane.
To get one of the vectors your code should be something like this:
Vector3 firstPoint = m_pointCloud.m_points[m_pointCloud.FindClosestPoint(Camera.main, new Vector2(Screen.width / 2, Screen.height / 2), 1)];
In this example I'm using the center of the screen as my Vector2 parameter. However you don't want the center of the screen . Instead you want the position of one corner from your plane translated as a screen point.
Hope that solves your problem. Cheers.
I am working on an endless jumper that turns into a faller type game. The camera on the way up is SUPER smooth, but on the way down it is extremely jerky.
I am not sure how to make it just follow the player with script and not jerk.
Camera going up:
float newHeightOfCamera = Mathf.Lerp(currentCameraHeight, playerHeightY, Time.deltaTime * 10);
transform.position = new Vector3(transform.position.x, newHeightOfCamera, transform.position.z);
Camera going down:
float newHeightOfCamera = Mathf.Lerp(currentCameraHeight, playerHeightY - fallCamera, Time.deltaTime);
transform.position = new Vector3(transform.position.x, newHeightOfCamera - cameraFallLocation, transform.position.z);
On the way down the player goes to the top of the screen and is set to a fixed speed.
pc.GetComponent<Rigidbody2D>().velocity = new Vector2(0, fallSpeed); //changes falling speed
I am still waiting for response to my comments, but for 90% your problem can be solved very easy with just moving all your code samples from Update to LateUpdate (or even from FixedUpdate to LateUpdate). In most cases that is enough. But still, we would need to know more details to be sure it is the solution.
Sorry I took a break from this game as it was frustrating. Here is what I came up with
This was for the falling. I didn't end up need the camera to catch up I just wanted it to be still.
float newHeightOfCamera = playerHeightY - fallCamera;
transform.position = new Vector3(transform.position.x, newHeightOfCamera - cameraFallLocation, transform.position.z);
fallCamera was the location of the camera. I wanted the character to be at the bottom of the screen when going up and at the top of the screen when going down.
I would like a RectTransform (panel) in Unity 4.6 to follow a worldObject. I got this working, but the movement is not as smooth as I'd like. It seems a bit jagged and it lags behind when I start moving the camera.
Vector2 followObjectScreenPos = Camera.main.WorldToScreenPoint (planet.transform.position);
rectTransform.anchoredPosition = new Vector2 (followObjectScreenPos.x - Screen.width / 2, followObjectScreenPos.y - Screen.height / 2);
Tips and tricks are greatly appreciated. :-)
There is a bunch of options:
1) You can add a gui canvas to the worldObject and render your panel with this canvas (just add it as a child), but that may not be exactly what you need.
2) To eliminate jagged movement you should tween in one way or another. DOTween is my personal preference, where something along the following lines would give you the required result:
Tweener tweener = transfrom.DOMove (Target.position, 1).SetSpeedBased();
tweener.OnUpdate (() => tweener.ChangeEndValue (Target.position, true));
3) if you don't want to include dependencies in your code, you can perform linear interpolation between current and desired position (or in your case - anchoredPosition) in Update function.
I'd suggest using a tweener so as not to clutter your update function and generally tweeners have loads of potential uses in all kinds of games.
Below is code sample for linear interpolation in case you don't want to use tweener library:
float smoothFactor = 1.0f; //used to sharpen or dull the effect of lerp
var newPosition = new Vector3(x,y,z);
var t = gameObject.transform;
t.position = Vector3.Lerp (t.position,
newPosition,
Time.deltaTime * smoothFactor);
Place it in Update function and it will make the gameObject follow specific newPosition.