質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • C#

    9675questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    6015questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity3D

    1977questions

    Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity GetComponentについて

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 635

Tats.N

score 54

こんにちは。いつもありがとうございます。
Unity、C#ともに初心者でわからないので質問させてください。

あるScriptから他のScript内のオブジェクトを削除するには

GetComponent<TexturePainter> ();でアクセスできると思っていたのですが、ある時はNullを、またある時はGetComponentを使ったところから下のコードが実行されません。

1つ目のコードが適応されている3dオブジェクトをクリックすると2つ目のコード内のbrushContainer内の子要素を削除したいのですが、どうすれば良いのでしょうか??

  1.  
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EraseCanvas : MonoBehaviour {
    //int brushCounter=0,MAX_BRUSH_COUNT=1000; //To avoid having millions of brushes
    public Material baseMaterial; // The material of our base texture (Were we will save the painted texture)
    public GameObject bContainer; //The cursor that overlaps the model and our container for the brushes painted
//    // Use this for initialization
//    void Start () {
//        
//    }

    // Update is called once per frame
    void Update(){
//        Debug.Log (brushContainer);
//        Debug.Log (GetComponent<TexturePainter> ());
//        Debug.Log (brushContainer);
        if(Input.GetMouseButtonDown(0)){
            Transform cam = Camera.main.transform;
            var ray = new Ray(cam.position, cam.forward);
            RaycastHit hit;
            if(Physics.Raycast (ray, out hit)){
                var e = hit.transform.GetComponent<EraseCanvas> ();
                if (e != null) {
                    Debug.Log ("|----------------------------------");
                    Debug.Log (bContainer.GetComponent<TexturePainter>().brushContainer);
                    Debug.Log ("----------------------------------|");
                    foreach (Transform child in bContainer.GetComponent<TexturePainter> ().brushContainer.transform) {//Clear brushes
                        Destroy(child.gameObject);
                        Debug.Log ("hi again");
                    }
                }
            }
        }
    }



    void ClearCanvas(){
        //brushCounter=0;
        //System.DateTime date = System.DateTime.Now;
//        //RenderTexture.active = canvasTexture;
//        Texture2D tex = new Texture2D(canvasTexture.width, canvasTexture.height, TextureFormat.RGB24, false);        
//        tex.ReadPixels (new Rect (0, 0, canvasTexture.width, canvasTexture.height), 0, 0);
//        tex.Apply ();
        //RenderTexture.active = null;
        //baseMaterial.mainTexture =tex;    //Put the painted texture as the base

        //StartCoroutine ("SaveTextureToFile"); //Do you want to save the texture? This is your method!
//        Invoke ("ShowCursor", 0.1f);
    }

}

2.呼び出そうとしているオブジェクトがあるコード

/// <summary>
/// CodeArtist.mx 2015
/// This is the main class of the project, its in charge of raycasting to a model and place brush prefabs infront of the canvas camera.
/// If you are interested in saving the painted texture you can use the method at the end and should save it to a file.
/// </summary>


using UnityEngine;
using UnityEngine.UI;
using System.Collections;


public enum Painter_BrushMode{PAINT,DECAL};
public class TexturePainter : MonoBehaviour {
    public GameObject brushCursor,brushContainer; //The cursor that overlaps the model and our container for the brushes painted
    public Camera sceneCamera,canvasCam;  //The camera that looks at the model, and the camera that looks at the canvas.
    public Sprite cursorPaint,cursorDecal; // Cursor for the differen functions 
    public RenderTexture canvasTexture; // Render Texture that looks at our Base Texture and the painted brushes
    public Material baseMaterial; // The material of our base texture (Were we will save the painted texture)

    Painter_BrushMode mode; //Our painter mode (Paint brushes or decals)
    float brushSize=1.0f; //The size of our brush
    public Color brushColor; //The selected color
    int brushCounter=0,MAX_BRUSH_COUNT=1000; //To avoid having millions of brushes
    bool saving=false; //Flag to check if we are saving the texture


    void Update () {
        //brushColor = ColorSelector.GetColor ();    //Updates our painted color with the selected color
        // brushColor = customBrushColor; // This is the brush color
        if (Input.GetMouseButton(0)) {
            DoAction();
        }
        UpdateBrushCursor ();
    }

    //The main action, instantiates a brush or decal entity at the clicked position on the UV map
    void DoAction(){    
        if (saving)
            return;
        Vector3 uvWorldPosition=Vector3.zero;        
        if(HitTestUVPosition(ref uvWorldPosition)){
            GameObject brushObj;
            if(mode==Painter_BrushMode.PAINT){

                brushObj=(GameObject)Instantiate(Resources.Load("TexturePainter-Instances/BrushEntity")); //Paint a brush
                brushObj.GetComponent<SpriteRenderer>().color=brushColor; //Set the brush color
            }
            else{
                brushObj=(GameObject)Instantiate(Resources.Load("TexturePainter-Instances/DecalEntity")); //Paint a decal
            }
            brushColor.a=brushSize*2.0f; // Brushes have alpha to have a merging effect when painted over.
            brushObj.transform.parent=brushContainer.transform; //Add the brush to our container to be wiped later
            brushObj.transform.localPosition=uvWorldPosition; //The position of the brush (in the UVMap)
            brushObj.transform.localScale=Vector3.one*brushSize;//The size of the brush
        }
        brushCounter++; //Add to the max brushes
        if (brushCounter >= MAX_BRUSH_COUNT) { //If we reach the max brushes available, flatten the texture and clear the brushes
            brushCursor.SetActive (false);
            saving=true;
            Invoke("SaveTexture",0.1f);

        }
    }
    //To update at realtime the painting cursor on the mesh
    void UpdateBrushCursor(){
        Vector3 uvWorldPosition=Vector3.zero;
        if (HitTestUVPosition (ref uvWorldPosition) && !saving) {
            brushCursor.SetActive(true);
            brushCursor.transform.position =uvWorldPosition+brushContainer.transform.position;                                    
        } else {
            brushCursor.SetActive(false);
        }        
    }
    //Returns the position on the texuremap according to a hit in the mesh collider
    bool HitTestUVPosition(ref Vector3 uvWorldPosition){
        RaycastHit hit;
        // Vector3 cursorPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0.0f);

        Vector3 cursorPos = new Vector3 (Screen.width/2, Screen.height/2, 0.0f);

        //Debug.Log("Screen.width/2 " + Screen.width/2);
        //Debug.Log("0.5f " + 0.5f);

        Ray cursorRay = sceneCamera.ScreenPointToRay (cursorPos);

        if (Physics.Raycast(cursorRay,out hit,200)){
            MeshCollider meshCollider = hit.collider as MeshCollider;

            var e = hit.transform.GetComponent<canvasScript> ();

            if (meshCollider == null || meshCollider.sharedMesh == null){
                return false;            
            }else if(e != null){
                Vector2 pixelUV  = new Vector2(hit.textureCoord.x,hit.textureCoord.y);
                uvWorldPosition.x=pixelUV.x-canvasCam.orthographicSize;//To center the UV on X
                uvWorldPosition.y=pixelUV.y-canvasCam.orthographicSize;//To center the UV on Y
                uvWorldPosition.z=0.0f;
                return true;
            }
        }
        else{        
            return false;
        }
        return false;

    }



    //Sets the base material with a our canvas texture, then removes all our brushes
    void SaveTexture(){        
        brushCounter=0;
        System.DateTime date = System.DateTime.Now;
        RenderTexture.active = canvasTexture;
        Texture2D tex = new Texture2D(canvasTexture.width, canvasTexture.height, TextureFormat.RGB24, false);        
        tex.ReadPixels (new Rect (0, 0, canvasTexture.width, canvasTexture.height), 0, 0);
        tex.Apply ();
        RenderTexture.active = null;
        baseMaterial.mainTexture =tex;    //Put the painted texture as the base
        foreach (Transform child in brushContainer.transform) {//Clear brushes
            Destroy(child.gameObject);
        }
        //StartCoroutine ("SaveTextureToFile"); //Do you want to save the texture? This is your method!
        Invoke ("ShowCursor", 0.1f);
    }
    //Show again the user cursor (To avoid saving it to the texture)
    void ShowCursor(){    
        saving = false;
    }

    ////////////////// PUBLIC METHODS //////////////////

    public void SetBrushMode(Painter_BrushMode brushMode){ //Sets if we are painting or placing decals
        mode = brushMode;
        brushCursor.GetComponent<SpriteRenderer> ().sprite = brushMode == Painter_BrushMode.PAINT ? cursorPaint : cursorDecal;
    }
    public void SetBrushSize(float newBrushSize){ //Sets the size of the cursor brush or decal
        brushSize = newBrushSize;
        brushCursor.transform.localScale = Vector3.one * brushSize;
    }

    ////////////////// OPTIONAL METHODS //////////////////

    #if !UNITY_WEBPLAYER 
        IEnumerator SaveTextureToFile(Texture2D savedTexture){        
            brushCounter=0;
            string fullPath=System.IO.Directory.GetCurrentDirectory()+"\\UserCanvas\\";
            System.DateTime date = System.DateTime.Now;
            string fileName = "CanvasTexture.png";
            if (!System.IO.Directory.Exists(fullPath))        
                System.IO.Directory.CreateDirectory(fullPath);
            var bytes = savedTexture.EncodeToPNG();
            System.IO.File.WriteAllBytes(fullPath+fileName, bytes);
            Debug.Log ("<color=orange>Saved Successfully!</color>"+fullPath+fileName);
            yield return null;
        }
    #endif
}

わかる方おられましたら、ご教授願います。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

「クリックしたオブジェクトに付いているEraseCanvas」が対象であるなら、
 foreach (Transform child in bContainer.GetComponent<TexturePainter> ().brushContainer.transform) {
の部分は、bContainerの前にe.を入れた
 foreach (Transform child in e.bContainer.GetComponent<TexturePainter> ().brushContainer.transform) {
になります。
(eが無いと「自分自身のbContainer」を対象にしようとします)

ちなみにここを直しても、以下の条件下でエラーが発生します。

  • bContainerがnullの時
  • bContainerにTexturePainterが付いていない時
  • bContainerのTexturePainterのbrushContainerがnullの時

これはUnityの仕様です。
なので適宜nullチェックを挟むか、絶対にnullが発生しないような構造とする
(スクリプト上で確実に変数にオブジェクトを入れる等)必要があるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C#

    9675questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    6015questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity3D

    1977questions

    Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。