Skip to main content
added 122 characters in body
Source Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

If your interface implementations differ only in the data they return from these getters, you might not need interfaces at all but a type object.

Then your platform script might be just an attachment point to glue this data structure to the game object:

public class Platform : MonoBehaviour {
    public PlatformProperties platformType;
}

And your PlatformProperties could be a ScriptableObject to make it easy to author in the editor and share between instances:

[CreateAssetMenu(fileName = "newPlatformProps.asset", menuName = "Level/Platform Properties")]
public class PlatformProperties : ScriptableObject {
    public Vector3 someProperty;
    // etc...
}

(You can of course use private serializable fields and getters to keep these things read-only if you want to enforce clean OOP here)

Determining whether the new platform is the same type as the old platform will still require getting a handle to the new platform — I can't tell you if "what's in the box" is the same as what's in my hand unless I open the box first.

But, we can at least detect whether we have a new box to open, rather than re-peeking into the same box every frame.

First, we cache the last platform collider and script we encountered:

Collider _lastCollider;
Platform _lastPlatform;

void OnCollisionEnter(Collision hit) {

Then in your collision handling logic (be it an OnCollisionEnter or a raycast/other test)...

     // Do things like discarding non-foot collisions
     // and updating grounded state here.

    if(hit.collider == _lastCollider) {
         // no news, early-out.
         return;
    }

    // Look for a platform script on the new platform
    var platform = hit.collider.gameObject.GetComponent<Platform>();

     if(platform == null)
         return; // Not a platform.

     _lastCollider = hit.collider

      if(platform.platformType != _oldPlatform.platformType) {
          // Here we know it's a new type.
     }
     _oldPlatform = platform;

    // ... etc

If your interface implementations differ only in the data they return from these getters, you might not need interfaces at all but a type object.

Then your platform script might be just an attachment point to glue this data structure to the game object:

public class Platform : MonoBehaviour {
    public PlatformProperties platformType;
}

And your PlatformProperties could be a ScriptableObject to make it easy to author in the editor and share between instances:

[CreateAssetMenu(fileName = "newPlatformProps.asset", menuName = "Level/Platform Properties")]
public class PlatformProperties : ScriptableObject {
    public Vector3 someProperty;
    // etc...
}

(You can of course use private serializable fields and getters to keep these things read-only if you want to enforce clean OOP here)

Determining whether the new platform is the same type as the old platform will still require getting a handle to the new platform — I can't tell you if "what's in the box" is the same as what's in my hand unless I open the box first.

But, we can at least detect whether we have a new box to open, rather than re-peeking into the same box every frame:

Collider _lastCollider;
Platform _lastPlatform;

void OnCollisionEnter(Collision hit) {
     // Do things like discarding non-foot collisions
     // and updating grounded state here.

    if(hit.collider == _lastCollider) {
         // no news, early-out.
         return;
    }

    // Look for a platform script on the new platform
    var platform = hit.collider.gameObject.GetComponent<Platform>();

     if(platform == null)
         return; // Not a platform.

     _lastCollider = hit.collider

      if(platform.platformType != _oldPlatform.platformType) {
          // Here we know it's a new type.
     }
     _oldPlatform = platform;

    // ... etc

If your interface implementations differ only in the data they return from these getters, you might not need interfaces at all but a type object.

Then your platform script might be just an attachment point to glue this data structure to the game object:

public class Platform : MonoBehaviour {
    public PlatformProperties platformType;
}

And your PlatformProperties could be a ScriptableObject to make it easy to author in the editor and share between instances:

[CreateAssetMenu(fileName = "newPlatformProps.asset", menuName = "Level/Platform Properties")]
public class PlatformProperties : ScriptableObject {
    public Vector3 someProperty;
    // etc...
}

(You can of course use private serializable fields and getters to keep these things read-only if you want to enforce clean OOP here)

Determining whether the new platform is the same type as the old platform will still require getting a handle to the new platform — I can't tell you if "what's in the box" is the same as what's in my hand unless I open the box first.

But, we can at least detect whether we have a new box to open, rather than re-peeking into the same box every frame.

First, we cache the last platform collider and script we encountered:

Collider _lastCollider;
Platform _lastPlatform;

Then in your collision handling logic (be it an OnCollisionEnter or a raycast/other test)...

     // Do things like discarding non-foot collisions
     // and updating grounded state here.

    if(hit.collider == _lastCollider) {
         // no news, early-out.
         return;
    }

    // Look for a platform script on the new platform
    var platform = hit.collider.gameObject.GetComponent<Platform>();

     if(platform == null)
         return; // Not a platform.

     _lastCollider = hit.collider

      if(platform.platformType != _oldPlatform.platformType) {
          // Here we know it's a new type.
     }
     _oldPlatform = platform;

    // ... etc
Source Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

If your interface implementations differ only in the data they return from these getters, you might not need interfaces at all but a type object.

Then your platform script might be just an attachment point to glue this data structure to the game object:

public class Platform : MonoBehaviour {
    public PlatformProperties platformType;
}

And your PlatformProperties could be a ScriptableObject to make it easy to author in the editor and share between instances:

[CreateAssetMenu(fileName = "newPlatformProps.asset", menuName = "Level/Platform Properties")]
public class PlatformProperties : ScriptableObject {
    public Vector3 someProperty;
    // etc...
}

(You can of course use private serializable fields and getters to keep these things read-only if you want to enforce clean OOP here)

Determining whether the new platform is the same type as the old platform will still require getting a handle to the new platform — I can't tell you if "what's in the box" is the same as what's in my hand unless I open the box first.

But, we can at least detect whether we have a new box to open, rather than re-peeking into the same box every frame:

Collider _lastCollider;
Platform _lastPlatform;

void OnCollisionEnter(Collision hit) {
     // Do things like discarding non-foot collisions
     // and updating grounded state here.

    if(hit.collider == _lastCollider) {
         // no news, early-out.
         return;
    }

    // Look for a platform script on the new platform
    var platform = hit.collider.gameObject.GetComponent<Platform>();

     if(platform == null)
         return; // Not a platform.

     _lastCollider = hit.collider

      if(platform.platformType != _oldPlatform.platformType) {
          // Here we know it's a new type.
     }
     _oldPlatform = platform;

    // ... etc