ページ 11

Unityでの関数参照について

Posted: 2015年8月22日(土) 19:32
by c#訓練者
はじめまして。
最近、UnityでC言語や3Dモデリングを勉強し始めたばかりの者です。
簡単プログラムはチュートリアルやリファレンスを元にかけるようにはなりました。
しかし、処理や変数をダラダラかくと汚くなってしまうので、関数を使い始めたのですが
関数内の変数の参照や変更を別関数で行うにはどうすればいいのでしょうか?
例えば、test2の中でtest1のaの値を5に変えたり、aの値を参照する。
Startで呼び出したtest1の実行結果を呼び出す、変更するなどです。

コード:

using UnityEngine;
using System.Collections;

public class rock: MonoBehaviour {
	void test1(){
		int a = 1;
		int b = 2;
		a += b;
		print (a);
	}

	void test2(){
		int c = 3;
		int d = 4;
		int e = 5;
	}

	void Start(){
		test1 ();
	}
}
unityのバージョン 5.1.1f1 64bit
OS win7 64bit
メモリ 8Gb
cpu i5 4460

Re: Unityでの関数参照について

Posted: 2015年8月22日(土) 19:39
by hide
その辺の考え方はC言語の範囲なので、C言語の入門書を使うといいかと思います

Re: Unityでの関数参照について

Posted: 2015年8月22日(土) 20:19
by softya(ソフト屋)
UnityでC言語は使えません。使えるのはC#でC言語とはまったくの別物です。
C#でtest1でもtest2でも参照・変更可能なのはクラスメンバ変数です。
C#の入門書を読んでもらえば書いてありますよ。

【補足】
ただ、引数や戻り値の利用を考えないプログラムはバグだらけになるので、そちらも学んでいただきです。
クラスメンバ変数の多用はバグを生み出しやすいですから。

Re: Unityでの関数参照について

Posted: 2015年8月23日(日) 01:33
by c#訓練者
何とか書き換え?はこれでできたようですが、参照方法はいまだに分かりません。
なぜこのようなことをしたいかというと、簡単なキャラクターのステータスの変動を1つのソースにまとめたかったからです。
例えば、関数1(経験値 HP最大値&現在値) 関数2(ダメージ処理) 関数3(回復処理) 関数4(経験値処理)
各関数で関数1を読み込んだり増減させるなど。

コード:

	void test1(){
		int a = 1;
		test2(ref a)
	}
	void test2(ref int a){
		a += 10;
	}
	void Start(){
		test1 ();
	}
softya(ソフト屋) さんが書きました:UnityでC言語は使えません。使えるのはC#でC言語とはまったくの別物です。
C#でtest1でもtest2でも参照・変更可能なのはクラスメンバ変数です。
C#の入門書を読んでもらえば書いてありますよ。

【補足】
ただ、引数や戻り値の利用を考えないプログラムはバグだらけになるので、そちらも学んでいただきです。
クラスメンバ変数の多用はバグを生み出しやすいですから。
>>ソフト屋さん
Unityでプログラムというものをさわり始めたばかりなので、c#とc+ c++についての違いがよく分かっておりませんでしたが、
調べてみて理解できました。つでに、引数、戻り値についても調べてみたのですが、引数と戻り値というのは下のコードの関数
int test3(int x)を例にとると
(int x)はtest4のx = 10が引き渡される(引数)でreturnで帰ってくる関数の実行結果が戻り値という感じでとらえたのですが、
合っていますでしょう?

コード:

	int test3(int x){
		int y = x + 10;
		return y;
	}

	void test4(){
		int x = 10;
		int z;
		z = test3 (x);

	}
	void Strat(){
		test4 ();
	}
この場合だと、test3の戻り値 20 引数 10 といった感じです。

Re: Unityでの関数参照について

Posted: 2015年8月23日(日) 14:09
by softya(ソフト屋)
refは変数を引数で参照受け渡してますので、受けた関数先で変数の値を変更できます。
が、この方法は場合によってソースコード見た時に分かりづらいので、使い方には注意が必要です。
変化するとわかりやすい方法は、戻り値と引数を使うことですね。

私が例で書いたクラスメンバ変数が使われていませんね。C#の場合フィールドと呼ぶみたいですが。
http://moeprog.web.fc2.com/School/Study ... /CS-29.htm
その他にもプロパティがありますが割愛します。勉強して下さい。
まぁ、こんな風に書けるんですがコンパイル・テストしてないのでエラーが出たらごめんなさい。

コード:

public class rock: MonoBehaviour {
	private int a,b;
	
    void test1(){
		test2();
        a += b;
        print (a);
    }
 
    void test2(){
        int c = 3;
        a = c + 1;
        b = c + 4;
    }
 
    void Start(){
        test1 ();
    }
}
わざと分かりづらく書きましたが、ちょっと変数の変化が分かりづらいですよね。

下に書かれているソースコードの戻り値と引数の理解は、それで良いと思いますよ。
しかしながら引数と戻りの多用し過ぎはオブジェクト指向言語のC#の特性を殺しかねません。
クラス・フィールド・プロパティ・メンバ関数の程よい活用が良いプログラムへの道筋になります。
最初から考え過ぎないことと もし分かりづらいなと思ったら面倒臭がらず分かりやすく直しているとだんだんと使い方がうまくなります。
慌てずに徐々にうまく使えるようになりましょう。最初はだれでも下手です。

Re: Unityでの関数参照について

Posted: 2015年8月24日(月) 11:02
by naohiro19
UnityでDLLの関数を呼び出すにはSystem.Runtime.InteropServices名前空間のDllImport属性を使います。
このサイトにあるUnManagedDllクラスを使います。
以下はWindows APIのMessageBox関数を呼び出す例です。

コード:

using System;
using System.Text;
using System.Runtime.InteropServices;
using MMFrame.Diagnostics;

public class WinAPI 
{
	private class Functions
	{
	    public delegate int MessageBox(IntPtr hwnd, string Text, string Caption, uint Type);
	}
	
	public WinAPI(string dllPath) : base(dllPath) {}
	
	public int MessageBox(IntPtr hwnd, string Text, string Caption, uint Type)
	{
	    return GetProcAddress<Functions.MessageBox>()(hwnd, Text, Caption, Type);
	}
}

//使う側
using(WinAPI dll = new WinAPI("User32"))
{
	dll.MessageBox(IntPtr.Zero, "テキスト","キャプション", 0x0);
}

Re: Unityでの関数参照について

Posted: 2015年8月24日(月) 13:58
by softya(ソフト屋)
naohiro19 さん、ちょっと唐突に感じるので意図を説明したほうが良いと思います。