And here’s what I meant originally. If you have the world move like this, then the Squids global position will truly move along with it, even though it appears to be standing still relative to background.
To get this global position, you use position, as opposed to localPosition, which is the actual position of the Squid relative to its parent. This is perhaps a confusing choice of words, on Unity’s part, but it is what it is. You’ll get used to it.
Now, let’s use this global position to influence sine motion.
public class SquidController : MonoBehaviour {
public float screenWidthInUnits = 1f; // will show up in inspector
public float sineFactor = 1f; // will show up in inspector
void Update() {
var pos = transform.localPosition;
pos = new Vector2(screenWidthInUnits * Mathf.Sin(transform.position.y * sineFactor), pos.y); // notice the difference
transform.localPosition = pos;
}
}
Additionally, in this example, you can make the squid look at the player i.e. but now you need to figure out how to get the player’s position.
In this case the simplest approach would be to expose such globally interesting information through some singleton object. Singleton means it is guaranteed to have just one instance, so that you don’t mistakenly copy its data and make a mess.
public class PublicInfo : MonoBehaviour {
static private PublicInfo _instance;
static public PublicInfo Instance => _instance;
public GameObject player; // we'll use this to hook up the player in the inspector
void Awake() { // when this object awakens it stores a reference to self to a static field above
_instance = this;
}
}
Now you attach this script to some empty top level gameobject, called Game for example.
Drag n drop Player from your hieararchy onto the eponymous field in the inspector of this script.
You can now access this field by calling PublicInfo.Instance.player from any other script.
And now, you can do this.
public class SquidController : MonoBehaviour {
public float screenWidthInUnits = 1f; // will show up in inspector
public float sineFactor = 1f; // will show up in inspector
void Update() {
// sine wave motion
var pos = transform.localPosition;
pos = new Vector2(screenWidthInUnits * Mathf.Sin(transform.position.y * sineFactor), pos.y);
transform.localPosition = pos;
// look at the player logic
var playerPos = PublicInfo.Instance.player.transform.localPosition;
var diffPos = playerPos - pos;
var angle = Math.Atan2(diffPos.y, diffPos.x); // in radians
// but Euler function accepts degrees so you need to multiply angle with this constant;
transform.localRotation = Quaternion.Euler(0f, 0f, angle * Mathf.Rad2Deg);
}
}
The reason why Euler looks like this (0f, 0f, something) is because the rotation is happening on the Z axis, because you’re working on the XY plane.
edit: made a mistake in how PublicInfo is accessed!