2015-05-14 16:05:58 cp790621656 阅读数 8110

Unity3d提供了功能可以让我们自己用各种语言编写 Plugin 来在Unity中使用,官方有简单的文档介绍

http://docs.unity3d.com/Manual/30_search.html?q=dllimport

之前的博文介绍了在 Android 平台使用C++ Plugin。

http://blog.csdn.net/huutu/article/details/43602659

本文在Win平台使用C++ DLL。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

编译一个简单的C++ DLL

首先来编译一个简单的C++ DLL供Unity3d 使用。转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

在VS 中选择控制台 项目

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

选择空项目 动态链接库

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

然后添加代码 Calculate.h   Calculate.cpp 文件。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

Calculate.h 代码如下:

# define _DLLExport __declspec (dllexport) //标记为导出函数;

extern "C" long long _DLLExport dlltest();


Calculate.cpp 代码如下:

#include "Calculate.h"

long long dlltest()
{
		long long a = 1;
		int b = 0;
		while(b<1000000000)
		{
			a=a+b;
			b++;
		}
		return a;
}

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

将 配置 修改为 Release ,我们编译一个Release 版本。 找到编译出来的 DLL文件,例如我这里是 TestDLL.dll 。

转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn

在Unity3d工程中使用DLL

创建一个Unity3d工程,在Assets 下创建 文件夹 Plugins 目录,把我们的DLL 文件 放到这个目录中。

测试代码如下:

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour {

	[DllImport ("TestDLL")]
	private static extern long dlltest();

	// Use this for initialization
	void Start () {
	
	}


	void OnGUI()
	{
		if(GUI.Button(new Rect(100,100,200,200),"Test DLL"))
		{
			long before=System.DateTime.Now.Ticks;
			Debug.Log("dlltest="+ dlltest());
			Debug.Log("take "+(System.DateTime.Now.Ticks-before));
		}

		if(GUI.Button(new Rect(300,300,200,200),"Test Mono"))
		{
			long before=System.DateTime.Now.Ticks;
			Debug.Log("monotest="+ monotest());
			Debug.Log("take "+(System.DateTime.Now.Ticks-before));
		}
	}

	// Update is called once per frame
	void Update () {
	
	}

	long monotest()
	{
		long a = 1;
		int b = 0;
		while(b<1000000000)
		{
			a=a+b;
			b++;
		}
		return a;
	}
}

使用DLL 中的函数要按照如下格式:

[DllImport ("TestDLL")]
	private static extern long dlltest();
转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn


DllImport 参数说明:

EntryPoint                 指定要调用的 DLL 入口点。

CharSet                    控制名称及函数中字符串参数的编码方式。默认值为 CharSet.Ansi。

ExactSpelling          是否修改入口点以对应不同的字符编码方式。

CallingConvention  指定用于传递方法参数的调用约定。默认值为 WinAPI。该值对应于基于32位Intel平台的 __stdcall。

BestFitMapping      是否启用最佳映射功能,默认为 true。最佳映射功能提供在没有匹配项时,自动提供匹配的字符


运行结果


示例工程下载:

http://download.csdn.net/detail/cp790621656/8699673


2019-02-09 13:40:07 qq_43667944 阅读数 64
               

因为Unity 采用C# 作为主要语言,代码编译之后作为DLL存在与执行文件中,这就给我们带来很大的一个问题,反编译非常容易。


如何反编译Unity游戏的代码:

Unity打包生成的安装包,我们随便下载一个游戏,解压APK,来到

assets\bin\Data\Managed

这个目录。

Assembly-CSharp.dllAssembly-CSharp-firstpass.dll

你在游戏中编写的代码就存放在这两个dll中。

把dll拖放到MonoDevelop中,稍等片刻,就能看到dll中的代码。


如果有一些比较重要的代码不想让别人看到,那就用C++来编写,C++编译成so文件,反编译之后只能成为汇编语言,无疑加大了破解难度(当然不能百分百防破解,汇编大牛很多的)


我们先新建一个文件夹,在里面新建一个jni文件夹,新建一个c文件,内容如下:

#include<string.h>  #include<jni.h>  int Share()return 1234561;}

就这么一个函数吧,供C#调用。


然后新建一个Android.mk文件,这是NDK编译SO需要的一个mk文件,在里面指定了如何编译。

LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  LOCAL_MODULE := Share  LOCAL_SRC_FILES := Share.c  include $(BUILD_SHARED_LIBRARY)

然后新建一个Application.mk文件,指定编译平台以及其它的依赖。

APP_ABI :=armeabi-v7aAPP_PLATFORM:=android-8APP_STL:=gnustl_staticAPP_CFLAGS += -Wno-error=format-security




然后在jni文件夹中执行命令:

ndk-build

就会编译出来so文件,存放在上一级的lib中。



新建一个Unity3d的工程,然后编写代码,调用so中的的函数。

using UnityEngine;using System.Collections;using System.IO;using System.Runtime.InteropServices;using System;public class test : MonoBehaviour { [DllImport("Share")private static extern int Share()// Use this for initialization void Start ()  {  Debug.Log("Shared = "+Share()); }  // Update is called once per frame void Update () {  }}

注意 如果要调用SO中的函数一定要按照Unity指定的规则来编写:

[DllImport("Share")]private static extern int Share();


在Unity工程中新建目录

Plugins\Android

拷贝SO文件到这里



然后我们导出APK安装测试



Demo工程下载:

http://download.csdn.net/detail/cp790621656/8430985



           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

2018-07-24 14:25:48 weixin_38340362 阅读数 147

UnityEngine.Object类是Unity 3D游戏引擎的C#脚本语言中最基本的类,也就是所有对象的基类。所有派生自UnityEngine.Object类的公开变量都会被显示在监视器inspector视窗中

Awake方法在start方法之前调用。换句话说,就是在prefab(预设)刚刚实例化之后便开始调用该方法。

OnEnable方法:这个函数在对象可用之后被调用

以上两个方法会在所有的start和update等方法之前被调用

即Awake()、OnEable()以及start()方法,完成了脚本的初始化工作。

FixedUpdate()方法比按帧执行的Update方法调用的次数可能更多,调用频率可能会更加的频繁。这是由于当帧率比较低的时候,该方法会被调用多次。该方法主要用来处理物理计算相关的逻辑,例如处理刚体。

Update()方法每一帧都会调用的方法。

LateUpdate()方法:在Update()执行之后,LateUpdate()也是每一帧都被调用,LateUpdate()方法的常见应用就是第三人称控制器的跟随。如果你把角色的移动和旋转放在Update()中,那么就可以把所有的相机的移动放在LateUpdate()中,这是因为在相机追踪角色位置之前,确保角色已经完成移动。或者说更加普遍的情形是:用来处理发生在Update()中,但是在相机渲染之前的逻辑。

 

2017-01-20 20:16:59 zzlyw 阅读数 4816

前言

Unity3D是一款非常优秀的游戏引擎,可以使用C#作为脚本语言进行编程。但是有的时候我们需要运行一些第三方的程序,例如C++实现的一些算法。我们需要将C++的代码以DLL的形式嵌入到Unity3D的程序中。这时候就要用到C#调用C++ DLL的方法。本文给出一个最简单的调用方式,实现了一些简单数据类型的传递。

 

1  C++中DLL的生成

在Windows平台上,首先使用VisualStudio2013来创建一个C++的Win32控制台应用程序。工程名设置为TestDLL。


在应用程序设置向导中,选择应用程序类型为DLL。


由于我们使用的Unity3D分32位和64位,所以我们需要在配置管理器中设置与Unity一致的位数。我的Unity3D是64位的,所以我做了如下设置。


然后将下面的代码粘贴到TestDll.cpp中。

#include "stdafx.h"

extern "C"_declspec(dllexport) void  fun0(int &a)
{
	a = 111;
}
extern "C"_declspec(dllexport) void  fun1(int *b)
{
	*b = 222;
}

extern "C"_declspec(dllexport) void  fun2(int c[])
{
	c[0] = 333;
}

extern "C"_declspec(dllexport) void  fun3(char *d)
{
	*d = 'B';
}


然后点击生成解决方案,就可以在“工程根目录\x64\Release”路径下看到生成的TestDll.dll。


2  在Unity3D中调用C++的DLL

创建一个新工程和一个新场景,并创建一个脚本UseDll.cs。脚本的内容如下:

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class UseDll : MonoBehaviour {

    [DllImport("TestDll")]
    private static extern void fun0(ref int a);
    [DllImport("TestDll")]
    private static extern void fun1(ref int b);
    [DllImport("TestDll")]
    private static extern void fun2(int[] c);
    [DllImport("TestDll")]
    private static extern void fun3(ref char d);

	void Start () {

        //初始化a、b、c、d 几个数据
        int a = 0;
        int b = 0;
        int[] c=new int[5];
        for(int i=0;i<5;i++)
        {
            c[i] = -1;
        }
        char d = 'A';
        

        //调用dll中的函数,对数据进行修改
        fun0(ref a);
        Debug.Log(a);
        fun1(ref b);
        Debug.Log(b);
        fun2(c);
        Debug.Log(c[0]);
        fun3( ref d);
        Debug.Log(d);
	
	}

	void Update () {
	
	}
}


将这个脚本绑定到摄像机上,并且要把上一步中生成的TestDll.dll拷贝一份放到“Unity工程根目录\Assets\Plugins”目录下。默认的时候Assets下是没有Plugins文件夹的,需要自己创建。一切就绪后,可以运行程序,在控制台显示如下信息,表示C#中初始化的数据已经在C++的DLL中被修改,即C#成功调用了C++的DLL。


2012-11-30 15:37:18 miaoweiye 阅读数 2698

 Unity3D支持三种脚本语言,javaScript、C#、Bool,Bool这种语言我不熟悉、不做评论,下面就说说javaScript与C#,我本人是搞C++,javaScript与C#这二种语言以前都没有接触过,通过这段时间对Unity3D的了解,我个人比较偏向与C#,最主要的就是C#的 delegate,通过C#的delegate可以调用其他脚本,而javaScript只能通过sendMessage这种方式,Unity3D是C++写的,所以我估计SendMessage的方式应该是MFC的方式是一样的,从运行速度、和代码的结构上来讲C#都是更好的选择。

当然也不排斥javaScript,不过我是真心的不喜欢这种弱类型的语言。下面是Delegate和SendMessage之间的优化性能差距测试

  1. using UnityEngine;  
  2. using System.Collections;  
  3. /// <summary>   
  4. /// Delegate basic.   
  5. /// just test Delegate && SendMessage ..   
  6. ///    
  7. /// By Chiuan 2012.8   
  8. /// </summary>   
  9. public class DelegateBasic : MonoBehaviour {  
  10.       
  11.     //define my delegate statement.   
  12.     public delegate void MyDelegate(string arg1);  
  13.       
  14.     //create my delegate object   
  15.     public MyDelegate myDelegate;  
  16.       
  17.     //need some values to debug time spent.   
  18.     bool isStart;  
  19.     float timeStart;  
  20.     int count;  
  21.       
  22.     bool isStartSendMessage;  
  23.       
  24.     // Use this for initialization   
  25.     void Start () {  
  26.         myDelegate += myFunciton1;  
  27.         //myDelegate += myFunciton2;   
  28.     }  
  29.       
  30.     // Update is called once per frame   
  31.     void Update () {  
  32.         if(isStart )  
  33.         {  
  34.             isStart = false;  
  35.             count = 0;  
  36.             timeStart = Time.realtimeSinceStartup;  
  37.             Debug.Log("Start = " + timeStart );  
  38.             for(int i= 0; i< 50000;i++)  
  39.             {  
  40.                 if(myDelegate != null) myDelegate("");  
  41.             }  
  42.         }  
  43.           
  44.         if(isStartSendMessage)  
  45.         {  
  46.             isStartSendMessage = false;  
  47.             count = 0;  
  48.             timeStart = Time.realtimeSinceStartup;  
  49.             Debug.Log("Start = " + timeStart );  
  50.             for(int i= 0; i< 50000;i++)  
  51.             {  
  52.                 this.gameObject.SendMessage("myFunciton1","",SendMessageOptions.DontRequireReceiver );  
  53.             }  
  54.         }  
  55.     }  
  56.       
  57.       
  58.     void OnGUI()  
  59.     {  
  60.         if(GUILayout.Button("INVOKE Delegate"))  
  61.         {  
  62.             isStart = true;  
  63.         }  
  64.           
  65.         if(GUILayout.Button("SendMessage"))  
  66.         {  
  67.             isStartSendMessage = true;  
  68.         }  
  69.           
  70.     }  
  71.       
  72.     void myFunciton1(string s)  
  73.     {  
  74.         count++;  
  75.         if(count == 50000)  
  76.         {  
  77.             Debug.Log("End = " + Time.realtimeSinceStartup );  
  78.             Debug.Log("Time Spent = " + ( Time.realtimeSinceStartup - timeStart ) );  
  79.         }  
  80.     }  
  81.       
  82.     void myFunciton2(string s)  
  83.     {  
  84.         //Debug.Log("myFunciton2 " + s);   
  85.     }  
  86.       
  87.       
  88. }  
没有更多推荐了,返回首页