-
-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement very basic look ahead functionality #284
base: main
Are you sure you want to change the base?
Conversation
I definitely see what you mean. What would make the most sense to me when trying to replicate the camera in question, would be framed follow mode, with the look ahead for it acting to offset the frame as well (and, therefore, give the player some leeway before shifting the camera the other way). Hollow Knight does something similar for the X axis, just without dead zones: Technically, Hollow Knight's camera's X axis behavior could be replicated by allowing the offset to persist, setting the As for the Mario camera, the same could be done, but with framed follow mode and checking if the frame moved instead of the However, I think you point out a good distinction in the sense that there is a difference between Mario and Hollow Knight's directional look ahead, and this PR's velocity based look ahead. The former is more so a "forward focus", and the latter a "velocity offset". Might be a good idea to split the look ahead functionality into these two instead, then, as it'd allow to recreate the Mario camera, but also with an additional offset that scales with velocity when going really fast (for a more momentum-based game). I.e.:
|
This is neat! Please correct me if I misinterpret how the values are being set and applied to the camera position. The challenge I see with defining min / max velocity and min offset values is that those values will, likely, need to change as the target's velocity speeds up or slows down. Whereas if it relies on time, then the velocity will dynamically change the The way I imagine it is that you would have the following properties:
I want to be careful about not overcomplicating the feature and being too opinionated about how it works — particularly for a first iteration. Think this is one of those things that can be done in many ways depending on the needs of a project. Can think of cases where a user would want to enable or disable the About the alternative way of toggling visibility for the |
I've been thinking about this one. It's technically just a I can think of a game where the movement and "looking" are decoupled (one using WASD, the other IJKL, for example). But then there are two options that the developer could want:
This is also why I think naming this functionality "Lookahead" could be a bit misleading, especially for people who have no knowledge of Cinemachine, as opposed to naming this some kind of "Velocity offset". One a side note -- in order to achieve this functionality using As for time vs. min/max velocity, I like the fact that it's effectively decoupled from the follow target's speed. I've gone with min/max velocity initally because it'd be easy to use different interpolation functions (your It'd technically be possible to have a "Lookahead min" and "Lookahead max" offset and use those for the interpolation. That is, calculate the offset depending on where the follow target will be in X seconds, and use that for the interpolation calculation if interpolation isn't set to none. I don't know how interpolation would interact with smoothing/damping in general, though; will have to experiment with that. |
I've gone with "smoothing" instead of "speed" for controlling the offset. There is a
|
There was a similar disucssion on Unity's forum about the Lookahead feature for Cinemachine. From that conversation, there is a seemingly agreed idea of allowing the Lookahead mechanic to not move back towards its targeted position based on a user defined parameter. Though as that was not included in Cinemachine, at least at this point in time, one can argue that it isn't needed for a first iteration for this feature. Just something to keep in mind if nothing else.
Think a solution to that could be a
I think both terms have merits. “Velocity offset” infers that the camera will change position, or be offset, due to changes in velocity. While “Lookahead” infers that the camera is looking further ahead from its current position. To my mind, the main interpretational difference is that “Lookahead” suggests that the camera is explicitly moving forward, whereas “Velocity Offset” implies that it's just being offset without a particular direction in mind. To your point, “Lookahead” in of itself doesn't necessarily tell the user what it will actually do and works more like an interpretive description rather than a technical one — similar to “damping” vs. “smoothing”. Though do think that's an easy solve with documentation or by the user enabling it themselves and trying it out. There is also an inverse risk of renaming something that people who are familiar with the feature in Cinemachine to something else that works the same way.
Not entirely sure how it would impact
Not sure if a
The above was based on some tests in the latest Cinemachine release in Unity 6. It also made me realize that For the smoothing operation itself, instead of the |
The equation is wrong, but the original idea was to not have any look ahead if the player is moving purely from user input, and then, when they get sped up by something for example, start applying look ahead (i.e. Ideally, I, as a plugin user, would like to supply the Phantom/Cinemachine camera with a custom function that takes in the velocity of the follow target and outputs the look ahead offset, but I have no idea what that entails from the plugin side of things. Will look into that out of curiosity, at the very least. Going with time will be simpler for the time being.
Completely unrelated to look ahead; since Framed Follow's camera has conditions during which it is stationary, there might be things the user wants to do when it starts moving (such as set a frame offset of some sort, depending on which direction it's moving). The idea came about when thinking about replicating the aforementioned Mario camera, but I'm not sure if Framed Follow is even the correct mode to choose.
I was thinking about this afterwards as well, and I completely agree. Though, I do think this sort of underlines the objectivity of what "looking" means.
I agree that "look ahead" conveys more meaning as to what direction the offset is getting applied in. While there are probably better names, such as "Forward offset" for an example, at that point it might as well be called just look ahead offset. After all, "coyote time" isn't time for coyotes either, is it? Will try to finish up and turn this into a proper pr in the near future. |
My understanding of Since the idea behind If it's a case of enabling or disabling
Isn't that effectively how the Would definitely suggest checking out the Cinemachine sample scenes that come with the latest package version, or some of the online videos showing how it functions in practice.
There could be a signal for detecting when a target touches the For the Mario example, one approach would be to tween from a If we're talking about detecting character movement in general, then it feels like it would make more sense for the user to make their own movement flag, kinda like
“Looking” is technically an impossibility in 2D environments, as all you can do is pan the camera in different directions. Think the key part of the phrase in “lookahead” is “ahead” given the directional connotation of the word. But you're right in that the exact meaning is nonsense the more you think about it.
Tech terminologies are funny. It's always about finding a balance between accuracy and comprehension. Sometimes, you just can't have both :D I'm generally leaning more towards comprehension even at the cost of technical accuracy, as ultimately the goal is to be as easily discoverable and understandable for others as possible. The main thing is to just ensure it doesn't obfuscate or mislead its purpose and functionality. The same applies to “physics interpolation”, which is apparently more accurate to refer to as “fixed timestep interpolation”. Though “physics interpolation” is probably still a bit of a vague term to many, “fixed timestep interpolation” is likely even more confusing in spite of being more accurate. |
As far as This lets me control the camera in a way where I can start applying the look-ahead offset at some velocity threshold. The time-based look-ahead doesn't allow me to do this in a way where I don't have to update a camera's properties at runtime, as far as I'm aware. As an example, I don't see an easy way of implementing a camera that:
This is conceptually a perfect fit for look-ahead offset, but impossible to implement using only look-ahead time, as the target could already have a considerable amount of velocity when it crosses over Again, the ideal solution to user defined look-ahead would be to allow the user to provide a function On a side note; the only way of specifying look-ahead in the Cinemachine docs that I've found was using time (namely in the Composer and Framing Transposer modules).
Exactly what I had in mind! |
To me, So, wonder if a simpler alternative to achieve what you describe, at least to start with, would be to expose the In any case, would prefer to keep the feature simple to start with, rather than adding everything to it for a first iteration. So limiting it to just an on/off toggle ( Adding a |
Compared to the old look ahead PR (#160), this has the disadvantage of being directly affected by
follow_damping
(though conceptually, I am completely fine with that). Otherwise, it is very reminiscent of the original, being implemented only for the 2DSIMPLE
mode with a follow target (as that is the main use case for me), but the@export
values are much friendlier for me to use personally.Additionally, I've included a potentially better way of defining
@export
property visibilities. This approach has the advantage of less code distance (i.e. being able to define a property's visibility right where you define it), but it also has the disadvantage of needing an editor reload every time you change when it should be visible. I'm also unsure of how it'd interact with otherproperty.usage
values, but they should co-exist peacefully in the_validate_property()
function. Note that this is merely a proposal.Still a few
TODO
s left at the very least; opening a PR to get input on the aforementioned, how to reconcile the 2 PRs together, and nitpicks of course :^).