2
\$\begingroup\$

A few weeks back I posted a question about keeping an object on the screen. What I would like to do now is clamping an object around a 2d radius based on the camera.

I'm need this for a reticule for this on rail shooter I've been making. (like that of starfox)

enter image description here

Here is the current code I am using :

        Vector3 movementx = transform.TransformDirection(Vector3.right * Input.GetAxis("Mouse X") * aimSpeed);
        Vector3 newPosx = transform.position + movementx;
        Vector3 offsetx = newPosx - centerPt.position;
        transform.position = centerPt.position + Vector3.ClampMagnitude(offsetx, radius);
// the same for the y axis 

The problem with this set up is that I'm restricting it around 3-dimensional objects base off their locations in the world. (this is restricting the players movement towards the edges not letting the player to move the reticule to the side)

So this is what I've tried:

   Vector3 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
   Vector3 shipOnScreen = Camera.main.WorldToScreenPoint(Ship.position);

        Vector3 movementx = transform.TransformDirection(Vector3.right * Input.GetAxis("Mouse X") * aimSpeed);
        Vector3 newPosx = screenPosition + movementx;
        Vector3 offsetx = newPosx - shipOnScreen;
        transform.position = shipOnScreen + Vector3.ClampMagnitude(offsetx, radius);
// the same for the y axis 

This just seems to send the empty (which the ship is pointing at) off some where else in the world I cant even tell if I'm moving it or if its just moving with the parent object. (I've tried different variations with this moving the screenPosition swapping it with the transforms position in world space to no avail)

My guess is that its not converting 2d space to 3d space when I try to clamp a 3d object within that radius.

I would like to keep my reticule at an empty point on the screen and not replace it with the cursor.

Edit:

Okay i have now thought up a new system that still needs some work. Having an empty object next to the reticule. With this I cut out the need for a 2d radius but I need this object object follow the ship on on the screen with taking in account the perception of the camera.

I have taken a measure of the height and width of the camera. Its not too exact but it should do.

So i guess I would like to know how the coordinate system on the camera is set up. like where is (0, 0)

update:

Okay I've found a way to do this but it took a quite a bit of math on my part and a bit of estimation on my behalf.

The way I've set it up is that I moving the pivot the same way I'm moving the ship only I'm multiplying it times the proportion of distance the ship can move side to side vs the distance the pivot can move side to side. I still have not built in an equation that will allow me to move the point farther back with more accuracy but this is a good temporary fix and if i really have to move it I'll i do the math again. but I would still like to have the equation of the rate of change. I'm not that brilliant at related rates. If you want to see my math I noted it down.

but if i can have an equation out of this it would work perfectly while changing

ship distance (constant) (61.6209, 27.5131)

first measure distance : 100

point A distance (320.5, 143.1)

5.20115872075484 y-multiplier

5.200473802917458 x-multiplier

so the multiplier at 100

5.2

distance : 50

point B distance (192.0436, 85.74551)

3.11633 y-multiplier

3.11633 x-multiplier

so the multiplier at 100

3.11633

Rate of change (5.2-3.1165)/(100-50) = ROC

ROC = 0.04166934

mt = 0.042

y = No idea

x = distances from ship

=0.042

Oh in case your wondering how i got my measurements I measured the distance manually with points.

enter image description here

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Hey i am sorry but cant understand your problem , there is lot of description and code its kind off confusing. Can you please describe the problem as briefly as you can may be two to three lines. \$\endgroup\$
    – Hash Buoy
    Commented Oct 22, 2015 at 19:56
  • \$\begingroup\$ Ha sorry this more or less turned into a log of me fixing this problem myself. I believe I now have created a final solution only that I haven't had a chance testing it but its seams that it will work but for the sake for other people I'll explain it again here in the comments. \$\endgroup\$
    – Ryan Henry
    Commented Oct 22, 2015 at 23:53
  • \$\begingroup\$ Cutting out some of the finer details I had two points on the screen. One in the for-ground and one in the back ground. The one in the background has to stay in front of the one in the for-ground the problem was that while it was in front of the object this did not count on the perception of the camera watching from behind. \$\endgroup\$
    – Ryan Henry
    Commented Oct 23, 2015 at 0:02
  • \$\begingroup\$ As I said I have pretty much answered this question myself and will post the answer once I test it out \$\endgroup\$
    – Ryan Henry
    Commented Oct 23, 2015 at 0:04
  • \$\begingroup\$ Ohh thats great \$\endgroup\$
    – Hash Buoy
    Commented Oct 23, 2015 at 4:28

1 Answer 1

1
\$\begingroup\$

It sounds like you've done a lot of math in 3D space to try and support this feature, taking into account the position of the ship and the camera, etc. But unless I'm missing something, I think there's an easier way.

This should work whether you want the game to be in first-person or third-person view.

  1. Add two empty Game Objects to your player object along the line of fire (in front of the ship), one farther away than the other.

enter image description here

  1. Make two reticle objects that look however you like. Make them children of the main camera.
  2. Place these reticles anywhere on the X and Y axes, but keep their positions on the Z axis right in front of the main camera, exactly at the near clipping plane.
  3. On the main camera or the Game Controller, write a Reticles Manager script. This script should watch the two empty game objects you placed in front of the ship and use Camera.WorldToScreenPoint to obtain their screen positions relative to the main camera. Once it has those positions, the Reticles Manager should move your two reticles to those two X and Y positions (keep the Z fixed at the near clipping plane).

In short, what you're doing is moving around some reticles right in front of your camera to overlap invisible objects you put in the player's line of fire.

If you don't want to have the reticles sitting in front of your main camera at the near clipping plane, which is usually pretty close, you can consider these options:

  • Put the reticles on their own layer. Make use of a second camera that renders only the reticles, while the main camera renders everything but.
  • Have the reticles live in the UI system.

Good luck!

\$\endgroup\$
2
  • \$\begingroup\$ Okay I have set things up that work. Only opposite of what you have just explained. I have created an object moving and the hud is attached to it. I didn't us Camera.WorldToScreenPoint in fact I did that manually through measurements. but all in all you did answer my original question so I think you should have the rights to the answer. \$\endgroup\$
    – Ryan Henry
    Commented Oct 28, 2015 at 4:25
  • \$\begingroup\$ Glad you solved it! \$\endgroup\$
    – Evan
    Commented Oct 30, 2015 at 2:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .