(Unity2D) Switch movement style on collision
I have a player character in a topdown game that moves in grid-like movements (1 unit at a time), but when it hits a patch of ice (square), I want it to switch to lerp-movement, slide to the edge, and stop.
Currently I have 5 different colliders as children for each patch of ice: the ice collider itself, and 4 slightly distanced colliders, one for each side of the ice. When it hits the ice collider, depending on which direction it was heading in, it should lerp to the distanced collider associated.
Like so (it's hard to see the main collider but it's there):
Here is the code I have been using for the down key (its basically the same for all keys):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
EDIT: code that updates bool 'onIce':
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
unity3d collision-detection lerp
|
show 5 more comments
I have a player character in a topdown game that moves in grid-like movements (1 unit at a time), but when it hits a patch of ice (square), I want it to switch to lerp-movement, slide to the edge, and stop.
Currently I have 5 different colliders as children for each patch of ice: the ice collider itself, and 4 slightly distanced colliders, one for each side of the ice. When it hits the ice collider, depending on which direction it was heading in, it should lerp to the distanced collider associated.
Like so (it's hard to see the main collider but it's there):
Here is the code I have been using for the down key (its basically the same for all keys):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
EDIT: code that updates bool 'onIce':
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
unity3d collision-detection lerp
So, whats exactly the problem?
– Hesamom
Nov 20 at 6:58
It's not sliding. It keeps using the 'else' case.
– Kat K
Nov 20 at 7:30
you should post the code that updates the "onIce" variable.
– Lotan
Nov 20 at 8:06
@Lotan I have updated it.
– Kat K
Nov 20 at 8:10
1
Is your collider a Trigger? If not, try OnCollisionEnter. Also try a non-friction physics material (assign it on the ice collider)
– KYL3R
Nov 20 at 8:18
|
show 5 more comments
I have a player character in a topdown game that moves in grid-like movements (1 unit at a time), but when it hits a patch of ice (square), I want it to switch to lerp-movement, slide to the edge, and stop.
Currently I have 5 different colliders as children for each patch of ice: the ice collider itself, and 4 slightly distanced colliders, one for each side of the ice. When it hits the ice collider, depending on which direction it was heading in, it should lerp to the distanced collider associated.
Like so (it's hard to see the main collider but it's there):
Here is the code I have been using for the down key (its basically the same for all keys):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
EDIT: code that updates bool 'onIce':
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
unity3d collision-detection lerp
I have a player character in a topdown game that moves in grid-like movements (1 unit at a time), but when it hits a patch of ice (square), I want it to switch to lerp-movement, slide to the edge, and stop.
Currently I have 5 different colliders as children for each patch of ice: the ice collider itself, and 4 slightly distanced colliders, one for each side of the ice. When it hits the ice collider, depending on which direction it was heading in, it should lerp to the distanced collider associated.
Like so (it's hard to see the main collider but it's there):
Here is the code I have been using for the down key (its basically the same for all keys):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
EDIT: code that updates bool 'onIce':
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
unity3d collision-detection lerp
unity3d collision-detection lerp
edited Nov 20 at 8:09
asked Nov 20 at 0:15
Kat K
325
325
So, whats exactly the problem?
– Hesamom
Nov 20 at 6:58
It's not sliding. It keeps using the 'else' case.
– Kat K
Nov 20 at 7:30
you should post the code that updates the "onIce" variable.
– Lotan
Nov 20 at 8:06
@Lotan I have updated it.
– Kat K
Nov 20 at 8:10
1
Is your collider a Trigger? If not, try OnCollisionEnter. Also try a non-friction physics material (assign it on the ice collider)
– KYL3R
Nov 20 at 8:18
|
show 5 more comments
So, whats exactly the problem?
– Hesamom
Nov 20 at 6:58
It's not sliding. It keeps using the 'else' case.
– Kat K
Nov 20 at 7:30
you should post the code that updates the "onIce" variable.
– Lotan
Nov 20 at 8:06
@Lotan I have updated it.
– Kat K
Nov 20 at 8:10
1
Is your collider a Trigger? If not, try OnCollisionEnter. Also try a non-friction physics material (assign it on the ice collider)
– KYL3R
Nov 20 at 8:18
So, whats exactly the problem?
– Hesamom
Nov 20 at 6:58
So, whats exactly the problem?
– Hesamom
Nov 20 at 6:58
It's not sliding. It keeps using the 'else' case.
– Kat K
Nov 20 at 7:30
It's not sliding. It keeps using the 'else' case.
– Kat K
Nov 20 at 7:30
you should post the code that updates the "onIce" variable.
– Lotan
Nov 20 at 8:06
you should post the code that updates the "onIce" variable.
– Lotan
Nov 20 at 8:06
@Lotan I have updated it.
– Kat K
Nov 20 at 8:10
@Lotan I have updated it.
– Kat K
Nov 20 at 8:10
1
1
Is your collider a Trigger? If not, try OnCollisionEnter. Also try a non-friction physics material (assign it on the ice collider)
– KYL3R
Nov 20 at 8:18
Is your collider a Trigger? If not, try OnCollisionEnter. Also try a non-friction physics material (assign it on the ice collider)
– KYL3R
Nov 20 at 8:18
|
show 5 more comments
1 Answer
1
active
oldest
votes
Lerp is only getting called once, when you push the button. One way to fix it is by using a coroutine:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
And then you use it like this:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
I think this is still not exactly what you want in your game because it will lerp to the center of the collider. If that's the case you can easily fix it by changing how it calculates the end variable in the coroutine to make the player only slide along the correct axis.
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384462%2funity2d-switch-movement-style-on-collision%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Lerp is only getting called once, when you push the button. One way to fix it is by using a coroutine:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
And then you use it like this:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
I think this is still not exactly what you want in your game because it will lerp to the center of the collider. If that's the case you can easily fix it by changing how it calculates the end variable in the coroutine to make the player only slide along the correct axis.
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
add a comment |
Lerp is only getting called once, when you push the button. One way to fix it is by using a coroutine:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
And then you use it like this:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
I think this is still not exactly what you want in your game because it will lerp to the center of the collider. If that's the case you can easily fix it by changing how it calculates the end variable in the coroutine to make the player only slide along the correct axis.
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
add a comment |
Lerp is only getting called once, when you push the button. One way to fix it is by using a coroutine:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
And then you use it like this:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
I think this is still not exactly what you want in your game because it will lerp to the center of the collider. If that's the case you can easily fix it by changing how it calculates the end variable in the coroutine to make the player only slide along the correct axis.
Lerp is only getting called once, when you push the button. One way to fix it is by using a coroutine:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
And then you use it like this:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
I think this is still not exactly what you want in your game because it will lerp to the center of the collider. If that's the case you can easily fix it by changing how it calculates the end variable in the coroutine to make the player only slide along the correct axis.
answered Nov 21 at 5:21
Leo Bartkus
831411
831411
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
add a comment |
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
It could also be off by one move.. because onIce will not be true until after you have already stepped on the ice. At the time of pressing the button when you first walk onto the ice, the player is not on the ice yet, and the trigger hasn't been hit yet.
– Leo Bartkus
Nov 21 at 5:28
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
I fixed the 'lerping to center issue' by changing 'end' to a Vector2, and making its x or y coordinate of 'end' the same as the player's, depending on which trigger it collided with. (i.e. if it hits the left trigger, use the player's y coordinate, etc.)
– Kat K
Nov 29 at 4:31
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384462%2funity2d-switch-movement-style-on-collision%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
So, whats exactly the problem?
– Hesamom
Nov 20 at 6:58
It's not sliding. It keeps using the 'else' case.
– Kat K
Nov 20 at 7:30
you should post the code that updates the "onIce" variable.
– Lotan
Nov 20 at 8:06
@Lotan I have updated it.
– Kat K
Nov 20 at 8:10
1
Is your collider a Trigger? If not, try OnCollisionEnter. Also try a non-friction physics material (assign it on the ice collider)
– KYL3R
Nov 20 at 8:18