error CS0117 'PhysicsMaterial2D' does not contain a definition for 'sharedMaterial'

Hello
I am trying to make a script which changes the material of the player’s Rigidbody2D upon colliding with an object with a specific tag but I am getting this error code. All of the documentation and threads I have looked at lead me to believe it should work but it isn’t so I’m rather confused. I’m trying to use a public array for the PhysicsMaterial2D so I can use the PhysicsMaterial2Ds for this use case with the player, while also keeping it customizable enough to where I could use the same script for different situations. How do I make it work properly?
P.S. This is the only type of error I am having with the script currently and its appearing at (9,27), (15,31), and (19,31)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMaterialSwapper : MonoBehaviour
{
    public PhysicsMaterial2D[] material;
    void Start()
  {
        PhysicsMaterial2D.sharedMaterial = material[0];
   }
    void onCollisionEnter(Collision2D col)
    {
        if (col.gameObject.tag == "Ball")
        {
            PhysicsMaterial2D.sharedMaterial = material[1];
        }
        else
        {
            PhysicsMaterial2D.sharedMaterial = material[2];
        }
    }
}

That is because PhysicsMaterial2D class doesnt have a static(or non-static) field called sharedMaterial. You can find all the fields of PhysicsMaterial2D in this page https://docs.unity3d.com/ScriptReference/PhysicsMaterial2D.html

when you type PhysicsMaterial2D.sharedMaterial this means that you are accessing a static field of the PhysicsMaterial2D class. If you had an actual physics material instance you would be able to use non-static fields too. For example:

var physicsMaterial = GetComponent<Collider2D>().sharedMaterial;//get the physics material of THIS GAMEOBJECT
print(physicsMaterial.name + " " + physicsMaterial.friction);

If you use an IDE like visual studio(free btw) you’ll be able to code much more efficiently. It’ll show you the available fields and methods and such when you start typing

2 Likes

You need a reference to the Rigidbody2D, which you will use to set the .sharedMaterial property.

You can also set that same material on Collider2D-derived things (2D colliders).

Be sure to understand what your code is doing.

This pattern is The Unity Way™… look for examples of it everywhere: get a reference by dragging something in, use that reference to do stuff. Live it, learn it, love it!

Intellisense is almost mandatory when starting out with a new environment, but this feature will tend to break every single time you create a new file in your project.

This may help you with intellisense and possibly other Visual Studio integration problems:

Sometimes the fix is as simple as doing Assets → Open C# Project from Unity. Other times it requires more.

Other times it requires you also nuke the userprefs and .vsconfig and other crufty low-value high-hassle files that Visual Studio tends to slowly damage over time, then try the above trick.

Barring all that, move on to other ideas:

https://discussions.unity.com/t/778503

Also, try update the VSCode package inside of Unity: Window → Package Manager → Search for Visual Studio Code Editor → Press the Update button

Also, this: https://discussions.unity.com/t/805330/7

1 Like

Unity stopped supporting VSCode , I’d recommend Visual Studio 2019. Never had a problem with it as long as it is marked as the external script editor and the “visual studio editor” package is installed

“Format document on save” and “HLSL tools for Visual studio” extensions help too

2 Likes

Ty! this has helped a lot and I am using visual studio 2019 (but im new to gamedev so my code might not look great :wink: )
I have managed to get it to stop giving errors but it still isn’t doing what it’s supposed to unfortunately.
Current Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMaterialSwapper : MonoBehaviour
{
  
    public PhysicsMaterial2D[] material;
    void Start()
  {
        var physicsMaterial = GetComponent<Rigidbody2D>().sharedMaterial;//get the physics material of THIS GAMEOBJECT
      //  print(physicsMaterial.name + " " + physicsMaterial.bounciness);
        physicsMaterial = material[0];
   }
 
    void onCollisionEnter(Collision2D col)
    {
        var physicsMaterial = GetComponent<Collider2D>().sharedMaterial;//get the physics material of THIS GAMEOBJECT
        if (col.gameObject.tag == "Ball")
        {
            physicsMaterial = material[1];
        }
        else
        {
            physicsMaterial = material[2];
        }
    }
}

I am assuming that the problem lies in lines 12, 20, and 24 as those are the ones determining the material.

C# is case sensitive AND it has a 2D suffix. It’s Unity - Scripting API: MonoBehaviour.OnCollisionEnter2D(Collision2D)

You need to be 100% accurate here.

It’s not clear what you’re trying to do here. Why do you get the material of the rigidbody then upon a collision get the material from the very first collider on this GameObject? Logically that doesn’t make sense.

void OnCollisionEnter2D(Collision2D col)
    {
        var collider = GetComponent<Collider2D>();
        if (col.gameObject.tag == "Ball")
        {
            collider.sharedMaterial = material[1];
        }
        else
        {
            collider.sharedMaterial = material[2];
        }
    }

Also, I see you grab material 1 or 2. Note that in C#, arrays start with index 0.

Seems like there’s a lot wrong here. You say you’re new to “game dev” but are you also new to C#? If so I’d definately recommend following some basic C# tutorials otherwise you’ll be struggling with the basics.

Yeah I’ve only been using C# for about a month and I think watching tutorials on the basics is a good idea because it is quite confusing

1 Like

It’s just a HUGE pile of connected knowledge, nothing anybody could ever soak up in a short period of time. You just sorta have to nibble at the edges of it and steadily build up your knowledge.

I find it helpful to organize areas of knowledge in my head as I learn. Broadly you will deal with three major areas, areas which I call “API buckets.” You may find this helpful to organize your learning:

  • C# language syntax (organization, structure, grammar, punctuation)
  • the .NET API (all the tools that come with C#: lists, dictionaries, file IO, etc)
  • the Unity API (everything in the using UnityEngine; namespace)

(See below for more on Unity’s component architecture)

But all of that is just the mechanics. You need to also consider how to solve the problem, and that’s just something that will slowly build the more you do it.

One technique is to repeatedly ask yourself, “Can I …?” and then go figure each little thing out, explaining it to your dog (see my avatar picture?) as you go along, or to your houseplant if you don’t have a dog.

Look at this guy’s approach:

Imphenzia: How Did I Learn To Make Games:

https://www.youtube.com/watch?v=b3DOnigmLBY

Unity’s component architecture

https://discussions.unity.com/t/808134/6

Terminology primer for assets:

https://discussions.unity.com/t/901952/2

1 Like

Tysm for the advice and the video! :smile: I think the asking “Can I?” strategy will work super well with me :slight_smile: With my first game that I’m currently working on I decided to make it simpler since complicated scripts, like the one that started the thread, are too much for me at the moment and I have found progress to be a lot more steady and enjoyable now! :smile:

1 Like

^ ^ ^ This is the key word. If you’re having fun, you’re winning already. Don’t stop!

1 Like