18-09-2022, 01:03 PM
(This post was last modified: 18-09-2022, 01:05 PM by josemendez.)
(18-09-2022, 11:46 AM)woffles Wrote: No problem, I've sent it to the address you specified.
While the project is with you, I've been trying to apply a force opposite to the direction of the softbody's collision. I've read through the collision scripting API and documentation and structured my own script to take the contact normal and use ObiSoftbody.AddForce(). However, it seems as though this has no effect.
Thank you as always!
Hi!
Took a look at your project, there's multiple issues with it so I will go over them one by one:
1) Lines 201-203 in your ObiSoftbody.cs look like this:
Code:
for (int j = 0; j < ac.batches[i].activeConstraintCount; ++j)
{; //<-- stray semicolon!
sc.batches[i].orientations[batchOffset + j] = rotOffset * sc.batches[i].orientations[batchOffset + j];
}
There's a semicolon immediately after the first { in the for loop.
2) You're calling Teleport() in your GameManager's Start(). By that time the solver hasn't created all constraints yet so attempting to teleport them will fail. You must wait for the solver to fully load the actor's constraints, this is done at the end of each frame where an actor has been loaded. So a simple fix would be:
Code:
public void ResetPosition()
{
StartCoroutine(ResetCoroutine());
}
public IEnumerator ResetCoroutine()
{
yield return new WaitForEndOfFrame(); // if this is the first frame, this makes sure constraint initialization has finished.
respawnPS.Play();
//GetComponent<Rigidbody>().velocity = Vector2.zero;
gameObject.transform.position = Vector3.zero;
softbody.Teleport(Vector3.zero, softbody.transform.rotation);
}
Also, there's no use on teleporting the softbody to the center during Start() so remove line 22 in SoftbodyBall.cs.
3) You're using a softbody for the ball, but it only has 2 triangles:
You won't get any meaningful deformation from this mesh, it will look just like a rigidbody. You need the mesh to have more subdivisions for it to be able to squish/deform, otherwise there's no point in using softbody simulation for this.
4) In your SoftbodyBouncySurface.cs, the "apply" boolean value is always false. As a result, no force is applied to the softbody.
The OnCollisionEnter2D callback only works for built-in colliders. Obi actors will ignore it, so you can delete the entire method. Here's a working script:
Code:
using System;
using System.Collections;
using Obi;
using UnityEngine;
public class SoftbodyBouncySurface : MonoBehaviour
{
public ObiSolver solver;
public SoftbodyBall softbody;
public float bounceStrength = 1000f;
private bool apply;
private Vector3 direction;
private void OnEnable()
{
solver.OnCollision += Solver_OnCollision;
}
private void OnDisable()
{
solver.OnCollision -= Solver_OnCollision;
}
private void Solver_OnCollision(object sender, ObiSolver.ObiCollisionEventArgs e)
{
// don't do anything if the force has not been applied yet.
if (apply) return;
var world = ObiColliderWorld.GetInstance();
// just iterate over all contacts in the current frame:
foreach (Oni.Contact contact in e.contacts)
{
// if this one is an actual collision:
if (contact.distance < 0.01)
{
ObiColliderBase col = world.colliderHandles[contact.bodyB].owner;
if (col.CompareTag("Paddle"))
{
direction = contact.normal;
apply = true;
return;
}
}
}
}
private void Update()
{
if (apply)
{
AudioManager.instance.PlaySound(3);
softbody.ApplyForce(direction * bounceStrength);
apply = false;
}
}
}
Keep in mind that impulses are affected by mass, since your ball weights 36 kg you must use a rather large bounceStrength value, try 1000-2000.
kind regards,