コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Rider】Unity において問題のあるコード(30パターン以上)には下線で警告が表示される

はじめに

f:id:baba_s:20190907194039p:plain

Rider で Unity 連携を有効化すると、Unity において問題のあるコードに
警告の波線が表示されたり、ハイライト表示されるようになります

この記事では、どのようなコードに警告の波線やハイライトが表示されるか紹介していきます

目次

Code Inspections

MonoBehaviour を継承したクラスを new している

'MonoBehaviour' instances must be instantiated with 'GameObject.AddComponent<T>()' instead of 'new'

f:id:baba_s:20190907193618p:plain

MonoBehaviour を継承したクラスは
new ではなく AddComponent で作成する必要があるため
new で作成している場合は警告の波線が表示されます

https://github.com/JetBrains/resharper-unity/wiki/MonoBehaviors-must-be-instantiated-with-GameObject.AddComponent-instead-of-new

ScriptableObject を継承したクラスを new している

'ScriptableObject' instances must be instantiated with 'ScriptableObject.CreateInstance<T>()' instead of 'new'

f:id:baba_s:20190907193624p:plain

ScriptableObject を継承したクラスは
new ではなく ScriptableObject.CreateInstance で作成する必要があるため
new で作成している場合は警告の波線が表示されます

https://github.com/JetBrains/resharper-unity/wiki/ScriptableObjects-must-be-instantiated-with-ScriptableObject.CreateInstance-instead-of-new

メモリ割り当てが発生する関数を使用している

Alternative non-allocating method available

f:id:baba_s:20190907193629p:plain

Physics.RaycastAll などの関数は、Physics.RaycastAllNonAlloc のように
メモリ割り当てが発生しない、名前に NonAlloc と付いたバージョンの関数が存在するため、
NonAlloc と付いたバージョンを使用していない場合は警告の波線が表示されます

f:id:baba_s:20190907193634p:plain

メモリ割り当てが発生しない、名前に NonAlloc と付いたバージョンの関数を使用すると
警告の波線が消えます

下記の関数は、メモリ割り当てが発生しない NonAlloc 版が存在します

関数 NonAlloc 版
Physics.BoxCastAll Physics.BoxCastNonAlloc
Physics.CapsuleCastAll Physics.CapsuleCastNonAlloc
Physics.RaycastAll Physics.RaycastNonAlloc
Physics.SphereCastAll Physics.SphereCastNonAlloc
Physics.OverlapBox Physics.OverlapBoxNonAlloc
Physics.OverlapCapsule Physics.OverlapCapsureNonAlloc
Physics.OverlapSphere Physics.OverlapSphereNonAlloc
Physics2D.BoxCastAll Physics2D.BoxCastNonAlloc
Physics2D.CapsuleCastAll Physics2D.CapsuleCastNonAlloc
Physics2D.CircleCastAll Physics2D.CircleCastNonAlloc
Physics2D.LinecastAll Physics2D.CapsuleCastNonAlloc
Physics2D.RaycastAll Physics2D.RaycastNonAlloc
Physics2D.GetRayIntersectionAll Physics2D.GetRayIntersectionNonAlloc
Physics2D.OverlapAreaAll Physics2D.OverlapAreaNonAlloc
Physics2D.OverlapBoxAll Physics2D.OverlapBoxNonAlloc
Physics2D.OverlapCapsuleAll Physics2D.OverlapCapsuleNonAlloc
Physics2D.OverlapCircleAll Physics2D.OverlapCircleNonAlloc
Physics2D.OverlapPointAll Physics2D.OverlapPointNonAlloc

https://github.com/JetBrains/resharper-unity/wiki/Avoid-using-allocating-versions-of-Physics-Raycast-functions

Unity エディタの表示崩れが発生するコードを記述している

Avoid 'base.OnGUI()' in classes derived from 'PropertyDrawer'

f:id:baba_s:20190907193647p:plain

PropertyDrawer の OnGUI の中で base.OnGUI を呼び出すと、表示崩れが発生するため
base.OnGUI を呼び出している場合は警告の波線が表示されます

イベント関数の引数が正しくない

Incorrect method signature

f:id:baba_s:20190907193652p:plain

Awake、Start、Update などの Unity が自動で呼び出す関数の引数が間違っている場合、
警告の波線が表示されます

処理に時間がかかる関数を使用している

Expensive method invocation

f:id:baba_s:20190907193658p:plain

Update や LateUpdate、FixedUpdate 、コルーチンなどは、
少し処理が遅いため、目立つようにハイライト表示されます

また、これらの関数の中で下記のような処理を記述した場合も
少し処理が遅くなる可能性があるため、ハイライト表示されます

  • AddComponent
  • GetComponent 系の関数
  • Find 系の関数
  • Debug.Log 系の関数
  • 文字列による関数呼び出し

https://github.com/JetBrains/resharper-unity/wiki/Performance-critical-context-and-costly-methods

UnityEngine.Object の null チェックを何回も呼び出している

Expensive null compatison

f:id:baba_s:20190907193707p:plain

UnityEngine.Object の null チェックは少し処理が遅いため、
Update や LateUpdate、FixedUpdate 、コルーチンなどの中で使用している場合、
ハイライト表示されます

Camera.main を何回も呼び出している

'Camera.main' is expensive

f:id:baba_s:20190907193714p:plain

Camera.main は少し処理が遅いため、Update や LateUpdate、FixedUpdate 、
コルーチンなどの中で使用している場合、ハイライト表示されます

FormerlySerializedAs 属性が正しく使用されていない

Possible incorrect application of attribute to multiple fields

f:id:baba_s:20190907193719p:plain

FormerlySerializedAs 属性を複数の変数定義に適用している場合、
警告の波線が表示されます

f:id:baba_s:20190907193726p:plain

このようなコードに書き直すことで警告の波線が消えます

https://github.com/JetBrains/resharper-unity/wiki/Possible-mis-application-of-FormerlySerializedAs-attribute-to-multiple-fields

UnityEngine.Object の null チェックに null 合体演算子を使用している

'??' on a type deriving from 'UnityEngine.Object' bypasses the lifetime check on the underlying Unity engine object

f:id:baba_s:20190907193732p:plain

UnityEngine.Object を継承しているインスタンスに対して null 合体演算子を使用すると、
null かどうかが正しくチェックできないことがあります

f:id:baba_s:20190907193752p:plain

このようなコードに書き直すことで警告の波線が消えます

UnityEngine.Object の null チェックに null 条件演算子を使用している

'?.' on a type deriving from 'UnityEngine.Object' bypasses the lifetime check on the underlying Unity engine object

f:id:baba_s:20190907193756p:plain

UnityEngine.Object を継承しているインスタンスに対して null 条件演算子を使用すると、
null かどうかが正しくチェックできないことがあります

f:id:baba_s:20190907193805p:plain

このようなコードに書き直すことで警告の波線が消えます

属性の指定が正しくない

Attribute is redundant when applied to this declaration type

f:id:baba_s:20190907193836p:plain

例えば、変数に適用するべき属性をプロパティに適用してしまっているなど、
属性の適用方法が間違っている場合、属性が暗めに表示されます

https://github.com/JetBrains/resharper-unity/wiki/Attribute-is-redundant-when-applied-to-this-declaration-type

FormerlySerializedAs 属性の指定が正しくない

Redundant 'FormerlySerializedAs' attribute

f:id:baba_s:20190907193855p:plain

FormerlySerializedAs 属性は、シリアライズされる変数に適用するものなので、
シリアライズされない変数に FormerlySerializedAs 属性を適用してしまっていると、
FormerlySerializedAs 属性が暗めに表示されます

HideInInspector 属性の指定が正しくない

Redundant 'HideInInspector' attribute

f:id:baba_s:20190907193902p:plain

HideInInspector 属性は、シリアライズされる変数に適用するものなので、
シリアライズされない変数に HideInInspector 属性を適用してしまっていると、
HideInInspector 属性が暗めに表示されます

InitializeOnLoad 属性の指定が正しくない

Redundant 'InitializeOnLoad' attribute

f:id:baba_s:20190907193909p:plain

InitializeOnLoad 属性は、static クラスに適用するものなので、
static ではないクラスに InitializeOnLoad 属性を適用してしまっていると、
InitializeOnLoad 属性が暗めに表示されます

SerializeField 属性の指定が正しくない

Redundant 'SerializeField' attribute

f:id:baba_s:20190907193915p:plain

NonSerialized 属性が適用されている変数に SerializeField 属性を適用しても
その変数はシリアライズされないため、SerializeField 属性が暗めに表示されます

イベント関数の中身が実装されていない

Redundant Unity event function

f:id:baba_s:20190907193924p:plain

Awake や Start、Update などの関数は中身が実装されていなくても
Unity から呼び出されてしまい、処理負荷が少しかかってしまうため、
Unity から呼び出されるが、中身が実装されていない関数は、暗めに表示されます

https://github.com/JetBrains/resharper-unity/wiki/Redundant-Unity-event-function

参照に時間がかかるプロパティを複数回参照している

Repeated access of property on built in component is inefficient

f:id:baba_s:20190907193931p:plain

transform.localPosition などは複数回参照するよりも、
一時変数に代入してから参照した方が良いパフォーマンスになるため、
transform.localPosition などを複数回参照している場合、警告の波線が表示されます

f:id:baba_s:20190907193935p:plain

このようなコードに書き直すことで警告の波線が消えます

https://github.com/JetBrains/resharper-unity/wiki/Avoid-multiple-unnecessary-property-accesses

Instantiate した後に親オブジェクトを設定している

Setting 'parent' property on built in component is inefficient

f:id:baba_s:20190907193952p:plain

オブジェクトを Instantiate してから親オブジェクトを設定するよりも
Instantiate の引数に親オブジェクトを指定した方が良いパフォーマンスになるため、
オブジェクトを Instantiate してから親オブジェクトを設定している場合、
警告の波線が表示されます

f:id:baba_s:20190907193958p:plain

このようなコードに書き直すことで警告の波線が消えます

https://github.com/JetBrains/resharper-unity/wiki/Avoid-using-Object.Instantiate-without-%E2%80%9CTransform-Parent%E2%80%9D-parameter-and-using-SetParent-later

Animator や Material のパラメータ指定に文字列を使っている

String based graphics property lookup is inefficient

f:id:baba_s:20190907194011p:plain

Animator や Material などのパラメータを設定する時は、パラメータ名を
文字列ではなくハッシュ値で指定した方が良いパフォーマンスになるため、
文字列でパラメータ名を指定している場合、警告の波線が表示されます

f:id:baba_s:20190907194016p:plain

このようなコードに書き直すことで警告の波線が消えます

https://github.com/JetBrains/resharper-unity/wiki/Prefer-using-generic-method-overload-instead-of-string

GetComponent などの関数で型名を文字列で指定している

String based lookup of component type is inefficient

f:id:baba_s:20190907194022p:plain

GetComponent などの関数を使用する時は、型名を文字列ではなく
ジェネリックで指定した方が良いパフォーマンスになるため、
文字列で型名を指定している場合、警告の波線が表示されます

f:id:baba_s:20190907194031p:plain

このようなコードに書き直すことで警告の波線が消えます

https://github.com/JetBrains/resharper-unity/wiki/Prefer-using-generic-method-overload-instead-of-string

タグの比較に CompareTag を使用していない

Use 'CompareTag' instead of explicit string comparison

f:id:baba_s:20190907194039p:plain

タグを比較する時は、tag プロパティではなく CompareTag を使用した方が
良いパフォーマンスになるため、tag プロパティを使用している場合、
警告の波線が表示されます

f:id:baba_s:20190907194043p:plain

このようなコードに書き直すことで警告の波線が消えます

https://github.com/JetBrains/resharper-unity/wiki/Use-CompareTag-instead-of-explicit-string-comparison

存在しないシーンファイルを指定している

Scene does not exist

f:id:baba_s:20190907201045p:plain

Unity プロジェクトに存在しないシーンの名前を
EditorSceneManager.OpenScene などで指定した場合、
警告の波線が表示されます

Build Settings で無効になっているシーンを指定している

Scene is disabled in the build settings

f:id:baba_s:20190907200936p:plain

Unity の Build Settings で無効になっているシーンの名前を
SceneManager.LoadScene などで指定した場合、
警告の波線が表示されます

Build Settings に複数設定されている同名のシーンを指定している

Short scene name is not unique

f:id:baba_s:20190907200936p:plain

Unity の Build Settings に同名のシーンファイルが複数設定されており、
そのシーン名を SceneManager.LoadScene などで指定した場合、
警告の波線が表示されます

同名のシーンファイルが Build Settings に複数設定されている場合は、
シーン名ではなくビルドインデックスを使用する必要があります

Build Settings に存在しないビルドインデックスを指定している

The index is missing in the build settings

f:id:baba_s:20190907200957p:plain

Unity の Build Settings に存在しないビルドインデックスを
SceneManager.LoadScene などで指定した場合、
警告の波線が表示されます

InputManager に存在しない名前を指定している

The input name is not defined in the Input manager

f:id:baba_s:20190907201006p:plain

Unity の InputManager に存在しない名前を Input.GetButtonDown などで指定した場合、
警告の波線が表示されます

存在しないレイヤーを指定している

The layers not defined in the 'Tags & Layers'

f:id:baba_s:20190907201013p:plain

存在しないレイヤーの名前を使用した場合、警告の波線が表示されます

存在しないタグを指定している

The tag is not defined in the 'Tags & Layers'

f:id:baba_s:20190907201033p:plain

存在しないタグの名前を使用した場合、警告の波線が表示されます

Build Settings に存在しないシーンを指定している

There is no scene with the same name in the build settings

f:id:baba_s:20190907200936p:plain

Unity の Build Settings に設定していないシーンの名前を
SceneManager.LoadScene などで指定した場合、
警告の波線が表示されます

設定変更

f:id:baba_s:20190907203446p:plain

Rider メニューの「File > Settings」から

f:id:baba_s:20190907203449p:plain

「Editor > Inspection Settings > Inspection Severity > C#」を選択して
「Unity」を選択すると、警告を表示するかどうかを変更できます